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