1 /* 2 Copyright (c) 2003-2009, CKSource - Frederico Knabben. All rights reserved. 3 For licensing, see LICENSE.html or http://ckeditor.com/license 4 */ 5 6 (function() 7 { 8 // Load image preview. 9 var IMAGE = 1, 10 LINK = 2, 11 PREVIEW = 4, 12 CLEANUP = 8, 13 regexGetSize = /^\s*(\d+)((px)|\%)?\s*$/i, 14 regexGetSizeOrEmpty = /(^\s*(\d+)((px)|\%)?\s*$)|^$/i; 15 16 var onSizeChange = function() 17 { 18 var value = this.getValue(), // This = input element. 19 dialog = this.getDialog(), 20 aMatch = value.match( regexGetSize ); // Check value 21 if ( aMatch ) 22 { 23 if ( aMatch[2] == '%' ) // % is allowed - > unlock ratio. 24 switchLockRatio( dialog, false ); // Unlock. 25 value = aMatch[1]; 26 } 27 28 // Only if ratio is locked 29 if ( dialog.lockRatio ) 30 { 31 var oImageOriginal = dialog.originalElement; 32 if ( oImageOriginal.getCustomData( 'isReady' ) == 'true' ) 33 { 34 if ( this.id == 'txtHeight' ) 35 { 36 if ( value != '' && value != 0 ) 37 value = Math.round( oImageOriginal.$.width * ( value / oImageOriginal.$.height ) ); 38 if ( !isNaN( value ) ) 39 dialog.setValueOf( 'info', 'txtWidth', value ); 40 } 41 else //this.id = txtWidth. 42 { 43 if ( value != '' && value != 0 ) 44 value = Math.round( oImageOriginal.$.height * ( value / oImageOriginal.$.width ) ); 45 if ( !isNaN( value ) ) 46 dialog.setValueOf( 'info', 'txtHeight', value ); 47 } 48 } 49 } 50 updatePreview( dialog ); 51 }; 52 53 var updatePreview = function( dialog ) 54 { 55 //Don't load before onShow. 56 if ( !dialog.originalElement || !dialog.preview ) 57 return 1; 58 59 // Read attributes and update imagePreview; 60 dialog.commitContent( PREVIEW, dialog.preview ); 61 return 0; 62 }; 63 64 var switchLockRatio = function( dialog, value ) 65 { 66 var oImageOriginal = dialog.originalElement, 67 ratioButton = CKEDITOR.document.getById( 'btnLockSizes' ); 68 69 if ( oImageOriginal.getCustomData( 'isReady' ) == 'true' ) 70 { 71 if ( value == 'check' ) // Check image ratio and original image ratio. 72 { 73 var width = dialog.getValueOf( 'info', 'txtWidth' ), 74 height = dialog.getValueOf( 'info', 'txtHeight' ), 75 originalRatio = oImageOriginal.$.width * 1000 / oImageOriginal.$.height, 76 thisRatio = width * 1000 / height; 77 dialog.lockRatio = false; // Default: unlock ratio 78 79 if ( width == 0 && height == 0 ) 80 dialog.lockRatio = true; 81 else if ( !isNaN( originalRatio ) && !isNaN( thisRatio )) 82 if ( Math.round( originalRatio ) == Math.round( thisRatio ) ) 83 dialog.lockRatio = true; 84 } 85 else if ( value != undefined ) 86 dialog.lockRatio = value 87 else 88 dialog.lockRatio = !dialog.lockRatio; 89 } 90 else if ( value != 'check' ) // I can't lock ratio if ratio is unknown. 91 dialog.lockRatio = false; 92 93 if ( dialog.lockRatio ) 94 ratioButton.removeClass( 'BtnUnlocked' ); 95 else 96 ratioButton.addClass( 'BtnUnlocked' ); 97 98 return dialog.lockRatio; 99 }; 100 101 var resetSize = function( dialog ) 102 { 103 var oImageOriginal = dialog.originalElement; 104 if ( oImageOriginal.getCustomData( 'isReady' ) == 'true' ) 105 { 106 dialog.setValueOf( 'info', 'txtWidth', oImageOriginal.$.width ); 107 dialog.setValueOf( 'info', 'txtHeight', oImageOriginal.$.height ); 108 } 109 updatePreview( dialog ); 110 }; 111 112 var setupDimension = function( type, element ) 113 { 114 if ( type != IMAGE ) 115 return 0; 116 117 var checkDimension = function( size, defaultValue ) 118 { 119 var aMatch = size.match( regexGetSize ); 120 if ( aMatch ) 121 { 122 if ( aMatch[2] == '%' ) // % is allowed. 123 { 124 aMatch[1] += '%'; 125 switchLockRatio( dialog, false ); // Unlock ratio 126 } 127 return aMatch[1]; 128 } 129 return defaultValue; 130 }, 131 dialog = this.getDialog(), 132 value = '', 133 dimension = (( this.id == 'txtWidth' )? 'width' : 'height' ), 134 size = element.getAttribute( dimension ); 135 136 if ( size ) 137 value = checkDimension( size, value ); 138 value = checkDimension( element.$.style[ dimension ], value ); 139 140 this.setValue( value ); 141 }; 142 143 var imageDialog = function( editor, dialogType ) 144 { 145 var onImgLoadEvent = function() 146 { 147 // Image is ready. 148 var original = this.originalElement; 149 original.setCustomData( 'isReady', 'true' ); 150 original.removeListener( 'load', onImgLoadEvent ); 151 original.removeListener( 'error', onImgLoadErrorEvent ); 152 original.removeListener( 'abort', onImgLoadErrorEvent ); 153 154 // Hide loader 155 CKEDITOR.document.getById( 'ImagePreviewLoader' ).setStyle( 'display', 'none' ); 156 157 // New image -> new domensions 158 if ( this.dontResetSize == false ) 159 resetSize( this ); 160 161 if ( this.firstLoad ) 162 switchLockRatio( this, 'check' ); 163 this.firstLoad = false; 164 this.dontResetSize = false; 165 }; 166 167 var onImgLoadErrorEvent = function() 168 { 169 // Error. Image is not loaded. 170 var original = this.originalElement; 171 original.removeListener( 'load', onImgLoadEvent ); 172 original.removeListener( 'error', onImgLoadErrorEvent ); 173 original.removeListener( 'abort', onImgLoadErrorEvent ); 174 175 // Set Error image. 176 var noimage = CKEDITOR.getUrl( 178 'skins/' + editor.config.skin + '/images/dialog.noimage.gif' ); 179 180 if ( this.preview ) 181 this.preview.setAttribute( 'src', noimage ); 182 183 // Hide loader 184 CKEDITOR.document.getById( 'ImagePreviewLoader' ).setStyle( 'display', 'none' ); 185 switchLockRatio( this, false ); // Unlock. 186 }; 187 return { 188 title : ( dialogType == 'image' ) ? editor.lang.image.title : editor.lang.image.titleButton, 189 minWidth : 450, 190 minHeight : 400, 191 onShow : function() 192 { 193 this.imageElement = false; 194 this.linkElement = false; 195 196 // Default: create a new element. 197 this.imageEditMode = false; 198 this.linkEditMode = false; 199 200 this.lockRatio = true; 201 this.dontResetSize = false; 202 this.firstLoad = true; 203 this.addLink = false; 204 205 //Hide loader. 206 CKEDITOR.document.getById( 'ImagePreviewLoader' ).setStyle( 'display', 'none' ); 207 // Preview 208 this.preview = CKEDITOR.document.getById( 'previewImage' ); 209 210 // IE BUG: Selection must be in the editor for getSelectedElement() 211 // to work. 212 this.restoreSelection(); 213 214 var editor = this.getParentEditor(), 215 element = this.getParentEditor().getSelection().getSelectedElement(); 216 217 // Copy of the image 218 this.originalElement = editor.document.createElement( 'img' ); 219 this.originalElement.setCustomData( 'isReady', 'false' ); 220 221 if ( element && element.getName() == 'a' ) 222 { 223 this.linkElement = element; 224 this.linkEditMode = true; 225 226 // Look for Image element. 227 var linkChildren = element.getChildren(); 228 if ( linkChildren.count() == 1 ) // 1 child. 229 { 230 var childTagName = linkChildren.getItem( 0 ).getName(); 231 if ( childTagName == 'img' || childTagName == 'input' ) 232 { 233 this.imageElement = linkChildren.getItem( 0 ); 234 if ( this.imageElement.getName() == 'img' ) 235 this.imageEditMode = 'img'; 236 else if ( this.imageElement.getName() == 'input' ) 237 this.imageEditMode = 'input'; 238 } 239 } 240 // Fill out all fields. 241 if ( dialogType == 'image' ) 242 this.setupContent( LINK, element ); 243 } 244 else if ( element && element.getName() == 'img' && !element.getAttribute( '_cke_protected_html' ) ) 245 this.imageEditMode = 'img'; 246 else if ( element && element.getName() == 'input' && element.getAttribute( 'type' ) && element.getAttribute( 'type' ) == 'image' ) 247 this.imageEditMode = 'input'; 248 249 if ( this.imageEditMode || this.imageElement ) 250 { 251 if ( !this.imageElement ) 252 this.imageElement = element; 253 254 // Fill out all fields. 255 this.setupContent( IMAGE, this.imageElement ); 256 257 // Refresh LockRatio button 258 switchLockRatio ( this, true ); 259 } 260 }, 261 onOk : function() 262 { 263 // Edit existing Image. 264 if ( this.imageEditMode ) 265 { 266 var imgTagName = this.imageEditMode, 267 removeObj = this.imageElement; 268 269 // Image dialog and Input element. 270 if ( dialogType == 'image' && imgTagName == 'input' && confirm( editor.lang.image.button2Img ) ) 271 { 272 // Replace INPUT-> IMG 273 imgTagName = 'img'; 274 this.imageElement = editor.document.createElement( 'img' ); 275 removeObj.insertBeforeMe( this.imageElement ); 276 removeObj.remove( false ); 277 278 } 279 // ImageButton dialog and Image element. 280 else if ( dialogType != 'image' && imgTagName == 'img' && confirm( editor.lang.image.img2Button )) 281 { 282 // Replace IMG -> INPUT 283 imgTagName = 'input'; 284 this.imageElement = editor.document.createElement( 'input' ); 285 this.imageElement.setAttribute ( 'type' ,'image' ); 286 removeObj.insertBeforeMe( this.imageElement ); 287 removeObj.remove( false ); 288 } 289 } 290 else // Create a new image. 291 { 292 // Image dialog -> create IMG element. 293 if ( dialogType == 'image' ) 294 this.imageElement = editor.document.createElement( 'img' ); 295 else 296 { 297 this.imageElement = editor.document.createElement( 'input' ); 298 this.imageElement.setAttribute ( 'type' ,'image' ); 299 } 300 } 301 302 // Create a new link. 303 if ( this.linkEditMode == false ) 304 this.linkElement = editor.document.createElement( 'a' ); 305 306 // Set attributes. 307 this.commitContent( IMAGE, this.imageElement ); 308 this.commitContent( LINK, this.linkElement ); 309 310 this.restoreSelection(); 311 this.clearSavedSelection(); 312 313 // Insert a new Image. 314 if ( this.imageEditMode == false ) 315 { 316 // It doesn't work with IE. 317 this.restoreSelection(); 318 this.clearSavedSelection(); 319 320 if ( this.addLink ) 321 //Insert a new Link. 322 if ( this.linkEditMode == false ) 323 { 324 this.linkElement.append( this.imageElement, false ); 325 editor.insertElement( this.linkElement ); 326 } 327 else //Link already exists, image not. 328 this.linkElement.append( this.imageElement, false ); 329 else 330 editor.insertElement( this.imageElement ); 331 } 332 else // Image already exists. 333 { 334 //Add a new link element. 335 if ( this.linkEditMode == false && this.addLink ) 336 { 337 this.imageElement.insertBeforeMe( this.linkElement ); 338 this.imageElement.appendTo( this.linkElement ); 339 } 340 //Remove Link, Image exists. 341 else if ( this.linkEditMode == true && this.addLink == false ) 342 this.linkElement.remove( true ); 343 } 344 }, 345 onLoad : function() 346 { 347 if ( dialogType != 'image' ) 348 this.hidePage( 'Link' ); //Hide Link tab. 349 }, 350 onHide : function() 351 { 352 if ( this.preview ) 353 this.commitContent( CLEANUP, this.preview ); 354 355 if ( this.originalElement ) 356 { 357 this.originalElement.removeListener( 'load', onImgLoadEvent ); 358 this.originalElement.removeListener( 'error', onImgLoadErrorEvent ); 359 this.originalElement.removeListener( 'abort', onImgLoadErrorEvent ); 360 this.originalElement.remove(); 361 this.originalElement = false; // Dialog is closed. 362 } 363 }, 364 contents : [ 365 { 366 id : 'info', 367 label : editor.lang.image.infoTab, 368 accessKey : 'I', 369 elements : 370 [ 371 { 372 type : 'vbox', 373 padding : 0, 374 children : 375 [ 376 { 377 type : 'html', 378 html : '<span>' + CKEDITOR.tools.htmlEncode( editor.lang.image.url ) + '</span>' 379 }, 380 { 381 type : 'hbox', 382 widths : [ '280px', '110px' ], 383 align : 'right', 384 children : 385 [ 386 { 387 id : 'txtUrl', 388 type : 'text', 389 label : '', 390 onChange : function() 391 { 392 var dialog = this.getDialog(), 393 newUrl = this.getValue(); 394 395 //Update original image 396 if ( newUrl.length > 0 ) //Prevent from load before onShow 397 { 398 var dialog = this.getDialog(), 399 original = dialog.originalElement; 400 401 original.setCustomData( 'isReady', 'false' ); 402 // Show loader 403 var loader = CKEDITOR.document.getById( 'ImagePreviewLoader' ); 404 if ( loader ) 405 loader.setStyle( 'display', '' ); 406 407 original.on( 'load', onImgLoadEvent, dialog ); 408 original.on( 'error', onImgLoadErrorEvent, dialog ); 409 original.on( 'abort', onImgLoadErrorEvent, dialog ); 410 original.setAttribute( 'src', newUrl ); 411 dialog.preview.setAttribute( 'src', newUrl ); 412 413 updatePreview( dialog ); 414 } 415 }, 416 setup : function( type, element ) 417 { 418 if ( type == IMAGE ) 419 { 420 var dialog = this.getDialog(); 421 var url = element.getAttribute( '_cke_saved_src' ); 422 if ( !url ) 423 url = element.getAttribute( 'src' ); 424 dialog.dontResetSize = true; 425 this.setValue( url ); // And call this.onChange() 426 this.focus(); 427 } 428 }, 429 commit : function( type, element ) 430 { 431 if ( type == IMAGE && ( this.getValue() != '' || this.isChanged() ) ) 432 { 433 element.setAttribute( '_cke_saved_src', decodeURI( this.getValue() ) ); 434 element.setAttribute( 'src', decodeURI( this.getValue() ) ); 435 } 436 else if ( type == CLEANUP ) 437 { 438 element.setAttribute( 'src', '' ); // If removeAttribute doesn't work. 439 element.removeAttribute( 'src' ); 440 } 441 } 442 }, 443 { 444 type : 'button', 445 id : 'browse', 446 align : 'center', 447 label : editor.lang.common.browseServer, 448 onLoad : function() 449 { 450 var dialog = this.getDialog(); 451 if ( dialog.getParentEditor().config.image_browseServer == false ) 452 dialog.getContentElement( 'info', 'browse' ).getElement().hide(); 453 }, 454 onClick : function() 455 { 456 457 } 458 } 459 ] 460 } 461 ] 462 }, 463 { 464 id : 'txtAlt', 465 type : 'text', 466 label : editor.lang.image.alt, 467 accessKey : 'A', 468 'default' : '', 469 onChange : function() 470 { 471 updatePreview( this.getDialog() ); 472 }, 473 setup : function( type, element ) 474 { 475 if ( type == IMAGE ) 476 this.setValue( element.getAttribute( 'alt' ) ); 477 }, 478 commit : function( type, element ) 479 { 480 if ( type == IMAGE ) 481 { 482 if ( this.getValue() != '' || this.isChanged() ) 483 element.setAttribute( 'alt', this.getValue() ); 484 } 485 else if ( type == PREVIEW ) 486 { 487 element.setAttribute( 'alt', this.getValue() ); 488 } 489 else if ( type == CLEANUP ) 490 { 491 element.removeAttribute( 'alt' ); 492 } 493 } 494 }, 495 { 496 type : 'hbox', 497 widths : [ '140px', '240px' ], 498 children : 499 [ 500 { 501 type : 'vbox', 502 padding : 10, 503 children : 504 [ 505 { 506 type : 'hbox', 507 widths : [ '70%', '30%' ], 508 children : 509 [ 510 { 511 type : 'vbox', 512 padding : 1, 513 children : 514 [ 515 { 516 type : 'text', 517 id : 'txtWidth', 518 labelLayout : 'horizontal', 519 label : editor.lang.image.width, 520 onKeyUp : onSizeChange, 521 validate: function() 522 { 523 var aMatch = this.getValue().match( regexGetSizeOrEmpty ); 524 if ( !aMatch ) 525 alert( editor.lang.common.validateNumberFailed ); 526 return !!aMatch; 527 }, 528 setup : setupDimension, 529 commit : function( type, element ) 530 { 531 if ( type == IMAGE ) 532 { 533 var value = this.getValue(); 534 if ( value != '' ) 535 element.setAttribute( 'width', value ); 536 else if ( value == '' && this.isChanged() ) 537 element.removeAttribute( 'width' ); 538 } 539 else if ( type == PREVIEW ) 540 { 541 var value = this.getValue(), 542 aMatch = value.match( regexGetSize ); 543 if ( !aMatch ) 544 { 545 var oImageOriginal = this.getDialog().originalElement; 546 if ( oImageOriginal.getCustomData( 'isReady' ) == 'true' ) 547 element.setStyle( 'width', oImageOriginal.$.width + 'px'); 548 } 549 else 550 element.setStyle( 'width', value + 'px'); 551 } 552 else if ( type == CLEANUP ) 553 { 554 element.setStyle( 'width', '0px' ); // If removeAttribute doesn't work. 555 element.removeAttribute( 'width' ); 556 element.removeStyle( 'width' ); 557 } 558 } 559 }, 560 { 561 type : 'text', 562 id : 'txtHeight', 563 labelLayout : 'horizontal', 564 label : editor.lang.image.height, 565 onKeyUp : onSizeChange, 566 validate: function() 567 { 568 var aMatch = this.getValue().match( regexGetSizeOrEmpty ); 569 if ( !aMatch ) 570 alert( editor.lang.common.validateNumberFailed ); 571 return !!aMatch; 572 }, 573 setup : setupDimension, 574 commit : function( type, element ) 575 { 576 if ( type == IMAGE ) 577 { 578 var value = this.getValue(); 579 if ( value != '' ) 580 element.setAttribute( 'height', value ); 581 else if ( value == '' && this.isChanged() ) 582 element.removeAttribute( 'height' ); 583 } 584 else if ( type == PREVIEW ) 585 { 586 var value = this.getValue(), 587 aMatch = value.match( regexGetSize ); 588 if ( !aMatch ) 589 { 590 var oImageOriginal = this.getDialog().originalElement; 591 if ( oImageOriginal.getCustomData( 'isReady' ) == 'true' ) 592 element.setStyle( 'height', oImageOriginal.$.height + 'px'); 593 } 594 else 595 element.setStyle( 'height', value + 'px'); 596 } 597 else if ( type == CLEANUP ) 598 { 599 element.setStyle( 'height', '0px' ); // If removeAttribute doesn't work. 600 element.removeAttribute( 'height' ); 601 element.removeStyle( 'height' ); 602 } 603 } 604 } 605 ] 606 }, 607 { 608 type : 'html', 609 style : 'position:relative;top:10px;height:50px;', 610 onLoad : function() 611 { 612 // Activate Reset button 613 var resetButton = CKEDITOR.document.getById( 'btnResetSize' ); 614 ratioButton = CKEDITOR.document.getById( 'btnLockSizes' ); 615 if ( resetButton ) 616 { 617 resetButton.on( 'click', function() 618 { 619 resetSize( this ); 620 }, this.getDialog() ); 621 resetButton.on( 'mouseover', function() 622 { 623 this.addClass( 'BtnOver' ); 624 }, resetButton ); 625 resetButton.on( 'mouseout', function() 626 { 627 this.removeClass( 'BtnOver' ); 628 }, resetButton ); 629 } 630 // Activate (Un)LockRatio button 631 if ( ratioButton ) 632 { 633 ratioButton.on( 'click', function() 634 { 635 var locked = switchLockRatio( this ), 636 oImageOriginal = this.originalElement, 637 width = this.getValueOf( 'info', 'txtWidth' ); 638 639 if ( oImageOriginal.getCustomData( 'isReady' ) == 'true' && width ) 640 { 641 var height = oImageOriginal.$.height / oImageOriginal.$.width * width; 642 if ( !isNaN( height ) ) 643 { 644 this.setValueOf( 'info', 'txtHeight', Math.round( height ) ); 645 updatePreview( this ); 646 } 647 } 648 }, this.getDialog() ); 649 ratioButton.on( 'mouseover', function() 650 { 651 this.addClass( 'BtnOver' ); 652 }, ratioButton ); 653 ratioButton.on( 'mouseout', function() 654 { 655 this.removeClass( 'BtnOver' ); 656 }, ratioButton ); 657 } 658 }, 659 html : '<div>'+ 660 '<div title="' + editor.lang.image.lockRatio + 661 '" class="BtnLocked" id="btnLockSizes"></div>' + 662 '<div title="' + editor.lang.image.resetSize + 663 '" class="BtnReset" id="btnResetSize"></div>'+ 664 '</div>' 665 } 666 ] 667 }, 668 { 669 type : 'vbox', 670 padding : 1, 671 children : 672 [ 673 { 674 type : 'text', 675 id : 'txtBorder', 676 labelLayout : 'horizontal', 677 label : editor.lang.image.border, 678 'default' : '', 679 onKeyUp : function() 680 { 681 updatePreview( this.getDialog() ); 682 }, 683 validate: function() 684 { 685 var func = CKEDITOR.dialog.validate.integer( editor.lang.common.validateNumberFailed ); 686 return func.apply( this ); 687 }, 688 setup : function( type, element ) 689 { 690 if ( type == IMAGE ) 691 this.setValue( element.getAttribute( 'border' ) ); 692 }, 693 commit : function( type, element ) 694 { 695 if ( type == IMAGE ) 696 { 697 if ( this.getValue() != '' || this.isChanged() ) 698 element.setAttribute( 'border', this.getValue() ); 699 } 700 else if ( type == PREVIEW ) 701 { 702 var value = parseInt( this.getValue(), 10 ); 703 value = isNaN( value ) ? 0 : value; 704 element.setAttribute( 'border', value ); 705 element.setStyle( 'border', value + 'px solid black' ); 706 } 707 else if ( type == CLEANUP ) 708 { 709 element.removeAttribute( 'border' ); 710 element.removeStyle( 'border' ); 711 } 712 } 713 }, 714 { 715 type : 'text', 716 id : 'txtHSpace', 717 labelLayout : 'horizontal', 718 label : editor.lang.image.hSpace, 719 'default' : '', 720 onKeyUp : function() 721 { 722 updatePreview( this.getDialog() ); 723 }, 724 validate: function() 725 { 726 var func = CKEDITOR.dialog.validate.integer( editor.lang.common.validateNumberFailed ); 727 return func.apply( this ); 728 }, 729 setup : function( type, element ) 730 { 731 if ( type == IMAGE ) 732 { 733 var value = element.getAttribute( 'hspace' ); 734 if ( value != -1 ) // In IE empty = -1. 735 this.setValue( value ); 736 } 737 }, 738 commit : function( type, element ) 739 { 740 if ( type == IMAGE ) 741 { 742 if ( this.getValue() != '' || this.isChanged() ) 743 element.setAttribute( 'hspace', this.getValue() ); 744 } 745 else if ( type == PREVIEW ) 746 { 747 var value = parseInt( this.getValue(), 10 ); 748 value = isNaN( value ) ? 0 : value; 749 element.setAttribute( 'hspace', value ); 750 element.setStyle( 'margin-left', value + 'px' ); 751 element.setStyle( 'margin-right', value + 'px' ); 752 } 753 else if ( type == CLEANUP ) 754 { 755 element.removeAttribute( 'hspace' ); 756 element.removeStyle( 'margin-left' ); 757 element.removeStyle( 'margin-right' ); 758 } 759 } 760 }, 761 { 762 type : 'text', 763 id : 'txtVSpace', 764 labelLayout : 'horizontal', 765 label : editor.lang.image.vSpace, 766 'default' : '', 767 onKeyUp : function() 768 { 769 updatePreview( this.getDialog() ); 770 }, 771 validate: function() 772 { 773 var func = CKEDITOR.dialog.validate.integer( editor.lang.common.validateNumberFailed ); 774 return func.apply( this ); 775 }, 776 setup : function( type, element ) 777 { 778 if ( type == IMAGE ) 779 this.setValue( element.getAttribute( 'vspace' ) ); 780 }, 781 commit : function( type, element ) 782 { 783 if ( type == IMAGE ) 784 { 785 if ( this.getValue() != '' || this.isChanged() ) 786 element.setAttribute( 'vspace', this.getValue() ); 787 } 788 else if ( type == PREVIEW ) 789 { 790 var value = parseInt( this.getValue(), 10 ); 791 value = isNaN( value ) ? 0 : value; 792 element.setAttribute( 'vspace', this.getValue() ); 793 element.setStyle( 'margin-top', value + 'px' ); 794 element.setStyle( 'margin-bottom', value + 'px' ); 795 } 796 else if ( type == CLEANUP ) 797 { 798 element.removeAttribute( 'vspace' ); 799 element.removeStyle( 'margin-top' ); 800 element.removeStyle( 'margin-bottom' ); 801 } 802 } 803 }, 804 { 805 id : 'cmbAlign', 806 type : 'select', 807 labelLayout : 'horizontal', 808 widths : [ '35%','65%' ], 809 style : 'width:100%', 810 label : editor.lang.image.align, 811 'default' : '', 812 items : 813 [ 814 [ editor.lang.common.notSet , ''], 815 [ editor.lang.image.alignLeft , 'left'], 816 [ editor.lang.image.alignAbsBottom , 'absBottom'], 817 [ editor.lang.image.alignAbsMiddle , 'absMiddle'], 818 [ editor.lang.image.alignBaseline , 'baseline'], 819 [ editor.lang.image.alignBottom , 'bottom'], 820 [ editor.lang.image.alignMiddle , 'middle'], 821 [ editor.lang.image.alignRight , 'right'], 822 [ editor.lang.image.alignTextTop , 'textTop'], 823 [ editor.lang.image.alignTop , 'top'] 824 ], 825 onKeyUp : function() 826 { 827 updatePreview( this.getDialog() ); 828 }, 829 setup : function( type, element ) 830 { 831 if ( type == IMAGE ) 832 this.setValue( element.getAttribute( 'align' ) ); 833 }, 834 commit : function( type, element ) 835 { 836 if ( type == IMAGE ) 837 { 838 if ( this.getValue() != '' || this.isChanged() ) 839 element.setAttribute( 'align', this.getValue() ); 840 } 841 else if ( type == PREVIEW ) 842 { 843 element.setAttribute( 'align', this.getValue() ); 844 } 845 else if ( type == CLEANUP ) 846 { 847 element.removeAttribute( 'align' ); 848 } 849 } 850 } 851 ] 852 } 853 ] 854 }, 855 { 856 type : 'vbox', 857 height : '250px', 858 children : 859 [ 860 { 861 type : 'html', 862 style : 'width:95%;', 863 html : '<div>' + CKEDITOR.tools.htmlEncode( editor.lang.image.preview ) +'<br>'+ 864 '<div id="ImagePreviewLoader" style="display:none"><div class="loading"> </div></div>'+ 865 '<div id="ImagePreviewBox">'+ 866 '<a href="javascript:void(0)" target="_blank" onclick="return false;" id="previewLink">'+ 867 '<img id="previewImage" src="" /></a>Lorem ipsum dolor sit amet, consectetuer adipiscing elit. '+ 868 'Maecenas feugiat consequat diam. Maecenas metus. Vivamus diam purus, cursus a, commodo non, facilisis vitae, '+ 869 '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.' + 870 '</div>'+'</div>' 871 } 872 ] 873 } 874 ] 875 } 876 ] 877 }, 878 { 879 id : 'Link', 880 label : editor.lang.link.title, 881 padding : 0, 882 elements : 883 [ 884 { 885 id : 'txtUrl', 886 type : 'text', 887 label : editor.lang.image.url, 888 style : 'width: 100%', 889 'default' : '', 890 setup : function( type, element ) 891 { 892 if ( type == LINK ) 893 { 894 var href = element.getAttribute( '_cke_saved_href' ); 895 if ( !href ) 896 href = element.getAttribute( 'href' ); 897 this.setValue( href ); 898 } 899 }, 900 commit : function( type, element ) 901 { 902 if ( type == LINK ) 903 if ( this.getValue() != '' || this.isChanged() ) 904 { 905 element.setAttribute( '_cke_saved_href', decodeURI( this.getValue() ) ); 906 element.setAttribute( 'href', 'javascript:void(0)/*' + 907 CKEDITOR.tools.getNextNumber() + '*/' ); 908 909 if ( this.getValue() != '' || editor.config.image_removeLinkByEmptyURL == false ) 910 this.getDialog().addLink = true; 911 } 912 } 913 }, 914 { 915 type : 'button', 916 id : 'browse', 917 style : 'float:right', 918 label : editor.lang.common.browseServer, 919 onClick : function() 920 { 921 } 922 }, 923 { 924 id : 'cmbTarget', 925 type : 'select', 926 label : editor.lang.link.target, 927 'default' : '', 928 items : 929 [ 930 [ editor.lang.link.targetNotSet , ''], 931 [ editor.lang.link.targetNew , '_blank'], 932 [ editor.lang.link.targetTop , '_top'], 933 [ editor.lang.link.targetSelf , '_self'], 934 [ editor.lang.link.targetParent , '_parent'] 935 ], 936 setup : function( type, element ) 937 { 938 if ( type == LINK ) 939 this.setValue( element.getAttribute( 'target' ) ); 940 }, 941 commit : function( type, element ) 942 { 943 if ( type == LINK ) 944 if ( this.getValue() != '' || this.isChanged() ) 945 element.setAttribute( 'target', this.getValue() ); 946 } 947 } 948 ] 949 }, 950 { 951 id : 'Upload', 952 label : editor.lang.image.upload, 953 elements : 954 [ 955 { 956 type : 'file', 957 id : 'upload', 958 label : editor.lang.image.btnUpload, 959 action : editor.config.image_uploadAction, 960 size : 38 961 }, 962 { 963 type : 'fileButton', 964 id : 'uploadButton', 965 label : editor.lang.image.btnUpload, 966 'for' : [ 'Upload', 'upload' ] 967 } 968 ] 969 }, 970 { 971 id : 'advanced', 972 label : editor.lang.common.advancedTab, 973 elements : 974 [ 975 { 976 type : 'hbox', 977 widths : [ '50%', '25%', '25%' ], 978 children : 979 [ 980 { 981 type : 'text', 982 id : 'linkId', 983 label : editor.lang.common.id, 984 setup : function( type, element ) 985 { 986 if ( type == IMAGE ) 987 this.setValue( element.getAttribute( 'id' ) ); 988 }, 989 commit : function( type, element ) 990 { 991 if ( type == IMAGE ) 992 if ( this.getValue() != '' || this.isChanged() ) 993 element.setAttribute( 'id', this.getValue() ); 994 } 995 }, 996 { 997 id : 'cmbLangDir', 998 type : 'select', 999 style : 'width : 100%;', 1000 label : editor.lang.common.langDir, 1001 'default' : '', 1002 items : 1003 [ 1004 [ editor.lang.common.notSet, '' ], 1005 [ editor.lang.common.langDirLtr, 'ltr' ], 1006 [ editor.lang.common.langDirRtl, 'rtl' ] 1007 ], 1008 setup : function( type, element ) 1009 { 1010 if ( type == IMAGE ) 1011 this.setValue( element.getAttribute( 'dir' ) ); 1012 }, 1013 commit : function( type, element ) 1014 { 1015 if ( type == IMAGE ) 1016 if ( this.getValue() != '' || this.isChanged() ) 1017 element.setAttribute( 'dir', this.getValue() ); 1018 } 1019 }, 1020 { 1021 type : 'text', 1022 id : 'txtLangCode', 1023 label : editor.lang.common.langCode, 1024 'default' : '', 1025 setup : function( type, element ) 1026 { 1027 if ( type == IMAGE ) 1028 this.setValue( element.getAttribute( 'lang' ) ); 1029 }, 1030 commit : function( type, element ) 1031 { 1032 if ( type == IMAGE ) 1033 if ( this.getValue() != '' || this.isChanged() ) 1034 element.setAttribute( 'lang', this.getValue() ); 1035 } 1036 } 1037 ] 1038 }, 1039 { 1040 type : 'text', 1041 id : 'txtGenLongDescr', 1042 label : editor.lang.common.longDescr, 1043 setup : function( type, element ) 1044 { 1045 if ( type == IMAGE ) 1046 this.setValue( element.getAttribute( 'longDesc' ) ); 1047 }, 1048 commit : function( type, element ) 1049 { 1050 if ( type == IMAGE ) 1051 if ( this.getValue() != '' || this.isChanged() ) 1052 element.setAttribute( 'longDesc', this.getValue() ); 1053 } 1054 }, 1055 { 1056 type : 'hbox', 1057 widths : [ '50%', '50%' ], 1058 children : 1059 [ 1060 { 1061 type : 'text', 1062 id : 'txtGenClass', 1063 label : editor.lang.common.cssClass, 1064 'default' : '', 1065 setup : function( type, element ) 1066 { 1067 if ( type == IMAGE ) 1068 this.setValue( element.getAttribute( 'class' ) ); 1069 }, 1070 commit : function( type, element ) 1071 { 1072 if ( type == IMAGE ) 1073 if ( this.getValue() != '' || this.isChanged() ) 1074 element.setAttribute( 'class', this.getValue() ); 1075 } 1076 }, 1077 { 1078 type : 'text', 1079 id : 'txtGenTitle', 1080 label : editor.lang.common.advisoryTitle, 1081 'default' : '', 1082 onChange : function() 1083 { 1084 updatePreview( this.getDialog() ); 1085 }, 1086 setup : function( type, element ) 1087 { 1088 if ( type == IMAGE ) 1089 this.setValue( element.getAttribute( 'title' ) ); 1090 }, 1091 commit : function( type, element ) 1092 { 1093 if ( type == IMAGE ) 1094 { 1095 if ( this.getValue() != '' || this.isChanged() ) 1096 element.setAttribute( 'title', this.getValue() ); 1097 } 1098 else if ( type == PREVIEW ) 1099 { 1100 element.setAttribute( 'title', this.getValue() ); 1101 } 1102 else if ( type == CLEANUP ) 1103 { 1104 element.removeAttribute( 'title' ); 1105 } 1106 } 1107 } 1108 ] 1109 }, 1110 { 1111 type : 'text', 1112 id : 'txtdlgGenStyle', 1113 label : editor.lang.common.cssStyle, 1114 'default' : '', 1115 setup : function( type, element ) 1116 { 1117 if ( type == IMAGE ) 1118 { 1119 var genStyle = element.getAttribute( 'style' ); 1120 if ( !genStyle && element.$.style.cssText ) 1121 genStyle = element.$.style.cssText; 1122 this.setValue( genStyle ); 1123 1124 var height = element.$.style.height, 1125 width = element.$.style.width, 1126 aMatchH = ( height ? height : '' ).match( regexGetSize ), 1127 aMatchW = ( width ? width : '').match( regexGetSize ); 1128 1129 this.attributesInStyle = 1130 { 1131 height : !!aMatchH, 1132 width : !!aMatchW 1133 } 1134 } 1135 }, 1136 commit : function( type, element ) 1137 { 1138 if ( type == IMAGE && ( this.getValue() != '' || this.isChanged() ) ) 1139 { 1140 element.setAttribute( 'style', this.getValue() ); 1141 1142 // Set STYLE dimensions. 1143 var height = element.getAttribute( 'height' ); 1144 width = element.getAttribute( 'width' ); 1145 1146 if ( this.attributesInStyle && this.attributesInStyle.height ) 1147 { 1148 if ( height && height != '' ) 1149 { 1150 if ( height.match( regexGetSize )[2] == '%' ) // % is allowed 1151 element.setStyle( 'height', height + '%' ); 1152 else 1153 element.setStyle( 'height', height + 'px' ); 1154 } 1155 else 1156 element.removeStyle( 'height' ); 1157 } 1158 if ( this.attributesInStyle && this.attributesInStyle.width ) 1159 { 1160 if ( width && width != '' ) 1161 if ( width.match( regexGetSize )[2] == '%' ) // % is allowed 1162 element.setStyle( 'width', width + '%' ); 1163 else 1164 element.setStyle( 'width', width + 'px' ); 1165 else 1166 element.removeStyle( 'width' ); 1167 } 1168 } 1169 } 1170 } 1171 ] 1172 } 1173 ] 1174 }; 1175 }; 1176 1177 CKEDITOR.dialog.add( 'image', function( editor ) 1178 { 1179 return imageDialog( editor, 'image' ) 1180 } 1181 ); 1182 1183 CKEDITOR.dialog.add( 'imagebutton', function( editor ) 1184 { 1185 return imageDialog( editor, 'imagebutton' ) 1186 } 1187 ); 1188 })(); 1189