image.js 45 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407
  1. /*
  2. Copyright (c) 2003-2011, CKSource - Frederico Knabben. All rights reserved.
  3. For licensing, see LICENSE.html or http://ckeditor.com/license
  4. */
  5. (function()
  6. {
  7. var imageDialog = function( editor, dialogType )
  8. {
  9. // Load image preview.
  10. var IMAGE = 1,
  11. LINK = 2,
  12. PREVIEW = 4,
  13. CLEANUP = 8,
  14. regexGetSize = /^\s*(\d+)((px)|\%)?\s*$/i,
  15. regexGetSizeOrEmpty = /(^\s*(\d+)((px)|\%)?\s*$)|^$/i,
  16. pxLengthRegex = /^\d+px$/;
  17. var onSizeChange = function()
  18. {
  19. var value = this.getValue(), // This = input element.
  20. dialog = this.getDialog(),
  21. aMatch = value.match( regexGetSize ); // Check value
  22. if ( aMatch )
  23. {
  24. if ( aMatch[2] == '%' ) // % is allowed - > unlock ratio.
  25. switchLockRatio( dialog, false ); // Unlock.
  26. value = aMatch[1];
  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. var updatePreview = function( dialog )
  53. {
  54. //Don't load before onShow.
  55. if ( !dialog.originalElement || !dialog.preview )
  56. return 1;
  57. // Read attributes and update imagePreview;
  58. dialog.commitContent( PREVIEW, dialog.preview );
  59. return 0;
  60. };
  61. // Custom commit dialog logic, where we're intended to give inline style
  62. // field (txtdlgGenStyle) higher priority to avoid overwriting styles contribute
  63. // by other fields.
  64. function commitContent()
  65. {
  66. var args = arguments;
  67. var inlineStyleField = this.getContentElement( 'advanced', 'txtdlgGenStyle' );
  68. inlineStyleField && inlineStyleField.commit.apply( inlineStyleField, args );
  69. this.foreach( function( widget )
  70. {
  71. if ( widget.commit && widget.id != 'txtdlgGenStyle' )
  72. widget.commit.apply( widget, args );
  73. });
  74. }
  75. // Avoid recursions.
  76. var incommit;
  77. // Synchronous field values to other impacted fields is required, e.g. border
  78. // size change should alter inline-style text as well.
  79. function commitInternally( targetFields )
  80. {
  81. if ( incommit )
  82. return;
  83. incommit = 1;
  84. var dialog = this.getDialog(),
  85. element = dialog.imageElement;
  86. if ( element )
  87. {
  88. // Commit this field and broadcast to target fields.
  89. this.commit( IMAGE, element );
  90. targetFields = [].concat( targetFields );
  91. var length = targetFields.length,
  92. field;
  93. for ( var i = 0; i < length; i++ )
  94. {
  95. field = dialog.getContentElement.apply( dialog, targetFields[ i ].split( ':' ) );
  96. // May cause recursion.
  97. field && field.setup( IMAGE, element );
  98. }
  99. }
  100. incommit = 0;
  101. }
  102. var switchLockRatio = function( dialog, value )
  103. {
  104. if ( !dialog.getContentElement( 'info', 'ratioLock' ) )
  105. return null;
  106. var oImageOriginal = dialog.originalElement;
  107. // Dialog may already closed. (#5505)
  108. if( !oImageOriginal )
  109. return null;
  110. // Check image ratio and original image ratio, but respecting user's preference.
  111. if ( value == 'check' )
  112. {
  113. if ( !dialog.userlockRatio && oImageOriginal.getCustomData( 'isReady' ) == 'true' )
  114. {
  115. var width = dialog.getValueOf( 'info', 'txtWidth' ),
  116. height = dialog.getValueOf( 'info', 'txtHeight' ),
  117. originalRatio = oImageOriginal.$.width * 1000 / oImageOriginal.$.height,
  118. thisRatio = width * 1000 / height;
  119. dialog.lockRatio = false; // Default: unlock ratio
  120. if ( !width && !height )
  121. dialog.lockRatio = true;
  122. else if ( !isNaN( originalRatio ) && !isNaN( thisRatio ) )
  123. {
  124. if ( Math.round( originalRatio ) == Math.round( thisRatio ) )
  125. dialog.lockRatio = true;
  126. }
  127. }
  128. }
  129. else if ( value != undefined )
  130. dialog.lockRatio = value;
  131. else
  132. {
  133. dialog.userlockRatio = 1;
  134. dialog.lockRatio = !dialog.lockRatio;
  135. }
  136. var ratioButton = CKEDITOR.document.getById( btnLockSizesId );
  137. if ( dialog.lockRatio )
  138. ratioButton.removeClass( 'cke_btn_unlocked' );
  139. else
  140. ratioButton.addClass( 'cke_btn_unlocked' );
  141. ratioButton.setAttribute( 'aria-checked', dialog.lockRatio );
  142. // Ratio button hc presentation - WHITE SQUARE / BLACK SQUARE
  143. if ( CKEDITOR.env.hc )
  144. {
  145. var icon = ratioButton.getChild( 0 );
  146. icon.setHtml( dialog.lockRatio ? CKEDITOR.env.ie ? '\u25A0': '\u25A3' : CKEDITOR.env.ie ? '\u25A1' : '\u25A2' );
  147. }
  148. return dialog.lockRatio;
  149. };
  150. var resetSize = function( dialog )
  151. {
  152. var oImageOriginal = dialog.originalElement;
  153. if ( oImageOriginal.getCustomData( 'isReady' ) == 'true' )
  154. {
  155. var widthField = dialog.getContentElement( 'info', 'txtWidth' ),
  156. heightField = dialog.getContentElement( 'info', 'txtHeight' );
  157. widthField && widthField.setValue( oImageOriginal.$.width );
  158. heightField && heightField.setValue( oImageOriginal.$.height );
  159. }
  160. updatePreview( dialog );
  161. };
  162. var setupDimension = function( type, element )
  163. {
  164. if ( type != IMAGE )
  165. return;
  166. function checkDimension( size, defaultValue )
  167. {
  168. var aMatch = size.match( regexGetSize );
  169. if ( aMatch )
  170. {
  171. if ( aMatch[2] == '%' ) // % is allowed.
  172. {
  173. aMatch[1] += '%';
  174. switchLockRatio( dialog, false ); // Unlock ratio
  175. }
  176. return aMatch[1];
  177. }
  178. return defaultValue;
  179. }
  180. var dialog = this.getDialog(),
  181. value = '',
  182. dimension = this.id == 'txtWidth' ? 'width' : 'height',
  183. size = element.getAttribute( dimension );
  184. if ( size )
  185. value = checkDimension( size, value );
  186. value = checkDimension( element.getStyle( dimension ), value );
  187. this.setValue( value );
  188. };
  189. var previewPreloader;
  190. var onImgLoadEvent = function()
  191. {
  192. // Image is ready.
  193. var original = this.originalElement;
  194. original.setCustomData( 'isReady', 'true' );
  195. original.removeListener( 'load', onImgLoadEvent );
  196. original.removeListener( 'error', onImgLoadErrorEvent );
  197. original.removeListener( 'abort', onImgLoadErrorEvent );
  198. // Hide loader
  199. CKEDITOR.document.getById( imagePreviewLoaderId ).setStyle( 'display', 'none' );
  200. // New image -> new domensions
  201. if ( !this.dontResetSize )
  202. resetSize( this );
  203. if ( this.firstLoad )
  204. CKEDITOR.tools.setTimeout( function(){ switchLockRatio( this, 'check' ); }, 0, this );
  205. this.firstLoad = false;
  206. this.dontResetSize = false;
  207. };
  208. var onImgLoadErrorEvent = function()
  209. {
  210. // Error. Image is not loaded.
  211. var original = this.originalElement;
  212. original.removeListener( 'load', onImgLoadEvent );
  213. original.removeListener( 'error', onImgLoadErrorEvent );
  214. original.removeListener( 'abort', onImgLoadErrorEvent );
  215. // Set Error image.
  216. var noimage = CKEDITOR.getUrl( editor.skinPath + 'images/noimage.png' );
  217. if ( this.preview )
  218. this.preview.setAttribute( 'src', noimage );
  219. // Hide loader
  220. CKEDITOR.document.getById( imagePreviewLoaderId ).setStyle( 'display', 'none' );
  221. switchLockRatio( this, false ); // Unlock.
  222. };
  223. var numbering = function( id )
  224. {
  225. return CKEDITOR.tools.getNextId() + '_' + id;
  226. },
  227. btnLockSizesId = numbering( 'btnLockSizes' ),
  228. btnResetSizeId = numbering( 'btnResetSize' ),
  229. imagePreviewLoaderId = numbering( 'ImagePreviewLoader' ),
  230. imagePreviewBoxId = numbering( 'ImagePreviewBox' ),
  231. previewLinkId = numbering( 'previewLink' ),
  232. previewImageId = numbering( 'previewImage' );
  233. return {
  234. title : editor.lang.image[ dialogType == 'image' ? 'title' : 'titleButton' ],
  235. minWidth : 420,
  236. minHeight : 360,
  237. onShow : function()
  238. {
  239. this.imageElement = false;
  240. this.linkElement = false;
  241. // Default: create a new element.
  242. this.imageEditMode = false;
  243. this.linkEditMode = false;
  244. this.lockRatio = true;
  245. this.userlockRatio = 0;
  246. this.dontResetSize = false;
  247. this.firstLoad = true;
  248. this.addLink = false;
  249. var editor = this.getParentEditor(),
  250. sel = this.getParentEditor().getSelection(),
  251. element = sel.getSelectedElement(),
  252. link = element && element.getAscendant( 'a' );
  253. //Hide loader.
  254. CKEDITOR.document.getById( imagePreviewLoaderId ).setStyle( 'display', 'none' );
  255. // Create the preview before setup the dialog contents.
  256. previewPreloader = new CKEDITOR.dom.element( 'img', editor.document );
  257. this.preview = CKEDITOR.document.getById( previewImageId );
  258. // Copy of the image
  259. this.originalElement = editor.document.createElement( 'img' );
  260. this.originalElement.setAttribute( 'alt', '' );
  261. this.originalElement.setCustomData( 'isReady', 'false' );
  262. if ( link )
  263. {
  264. this.linkElement = link;
  265. this.linkEditMode = true;
  266. // Look for Image element.
  267. var linkChildren = link.getChildren();
  268. if ( linkChildren.count() == 1 ) // 1 child.
  269. {
  270. var childTagName = linkChildren.getItem( 0 ).getName();
  271. if ( childTagName == 'img' || childTagName == 'input' )
  272. {
  273. this.imageElement = linkChildren.getItem( 0 );
  274. if ( this.imageElement.getName() == 'img' )
  275. this.imageEditMode = 'img';
  276. else if ( this.imageElement.getName() == 'input' )
  277. this.imageEditMode = 'input';
  278. }
  279. }
  280. // Fill out all fields.
  281. if ( dialogType == 'image' )
  282. this.setupContent( LINK, link );
  283. }
  284. if ( element && element.getName() == 'img' && !element.data( 'cke-realelement' )
  285. || element && element.getName() == 'input' && element.getAttribute( 'type' ) == 'image' )
  286. {
  287. this.imageEditMode = element.getName();
  288. this.imageElement = element;
  289. }
  290. if ( this.imageEditMode )
  291. {
  292. // Use the original element as a buffer from since we don't want
  293. // temporary changes to be committed, e.g. if the dialog is canceled.
  294. this.cleanImageElement = this.imageElement;
  295. this.imageElement = this.cleanImageElement.clone( true, true );
  296. // Fill out all fields.
  297. this.setupContent( IMAGE, this.imageElement );
  298. }
  299. else
  300. this.imageElement = editor.document.createElement( 'img' );
  301. // Refresh LockRatio button
  302. switchLockRatio ( this, true );
  303. // Dont show preview if no URL given.
  304. if ( !CKEDITOR.tools.trim( this.getValueOf( 'info', 'txtUrl' ) ) )
  305. {
  306. this.preview.removeAttribute( 'src' );
  307. this.preview.setStyle( 'display', 'none' );
  308. }
  309. },
  310. onOk : function()
  311. {
  312. // Edit existing Image.
  313. if ( this.imageEditMode )
  314. {
  315. var imgTagName = this.imageEditMode;
  316. // Image dialog and Input element.
  317. if ( dialogType == 'image' && imgTagName == 'input' && confirm( editor.lang.image.button2Img ) )
  318. {
  319. // Replace INPUT-> IMG
  320. imgTagName = 'img';
  321. this.imageElement = editor.document.createElement( 'img' );
  322. this.imageElement.setAttribute( 'alt', '' );
  323. editor.insertElement( this.imageElement );
  324. }
  325. // ImageButton dialog and Image element.
  326. else if ( dialogType != 'image' && imgTagName == 'img' && confirm( editor.lang.image.img2Button ))
  327. {
  328. // Replace IMG -> INPUT
  329. imgTagName = 'input';
  330. this.imageElement = editor.document.createElement( 'input' );
  331. this.imageElement.setAttributes(
  332. {
  333. type : 'image',
  334. alt : ''
  335. }
  336. );
  337. editor.insertElement( this.imageElement );
  338. }
  339. else
  340. {
  341. // Restore the original element before all commits.
  342. this.imageElement = this.cleanImageElement;
  343. delete this.cleanImageElement;
  344. }
  345. }
  346. else // Create a new image.
  347. {
  348. // Image dialog -> create IMG element.
  349. if ( dialogType == 'image' )
  350. this.imageElement = editor.document.createElement( 'img' );
  351. else
  352. {
  353. this.imageElement = editor.document.createElement( 'input' );
  354. this.imageElement.setAttribute ( 'type' ,'image' );
  355. }
  356. this.imageElement.setAttribute( 'alt', '' );
  357. }
  358. // Create a new link.
  359. if ( !this.linkEditMode )
  360. this.linkElement = editor.document.createElement( 'a' );
  361. // Set attributes.
  362. this.commitContent( IMAGE, this.imageElement );
  363. this.commitContent( LINK, this.linkElement );
  364. // Remove empty style attribute.
  365. if ( !this.imageElement.getAttribute( 'style' ) )
  366. this.imageElement.removeAttribute( 'style' );
  367. // Insert a new Image.
  368. if ( !this.imageEditMode )
  369. {
  370. if ( this.addLink )
  371. {
  372. //Insert a new Link.
  373. if ( !this.linkEditMode )
  374. {
  375. editor.insertElement( this.linkElement );
  376. this.linkElement.append( this.imageElement, false );
  377. }
  378. else //Link already exists, image not.
  379. editor.insertElement( this.imageElement );
  380. }
  381. else
  382. editor.insertElement( this.imageElement );
  383. }
  384. else // Image already exists.
  385. {
  386. //Add a new link element.
  387. if ( !this.linkEditMode && this.addLink )
  388. {
  389. editor.insertElement( this.linkElement );
  390. this.imageElement.appendTo( this.linkElement );
  391. }
  392. //Remove Link, Image exists.
  393. else if ( this.linkEditMode && !this.addLink )
  394. {
  395. editor.getSelection().selectElement( this.linkElement );
  396. editor.insertElement( this.imageElement );
  397. }
  398. }
  399. },
  400. onLoad : function()
  401. {
  402. if ( dialogType != 'image' )
  403. this.hidePage( 'Link' ); //Hide Link tab.
  404. var doc = this._.element.getDocument();
  405. if ( this.getContentElement( 'info', 'ratioLock' ) )
  406. {
  407. this.addFocusable( doc.getById( btnResetSizeId ), 5 );
  408. this.addFocusable( doc.getById( btnLockSizesId ), 5 );
  409. }
  410. this.commitContent = commitContent;
  411. },
  412. onHide : function()
  413. {
  414. if ( this.preview )
  415. this.commitContent( CLEANUP, this.preview );
  416. if ( this.originalElement )
  417. {
  418. this.originalElement.removeListener( 'load', onImgLoadEvent );
  419. this.originalElement.removeListener( 'error', onImgLoadErrorEvent );
  420. this.originalElement.removeListener( 'abort', onImgLoadErrorEvent );
  421. this.originalElement.remove();
  422. this.originalElement = false; // Dialog is closed.
  423. }
  424. delete this.imageElement;
  425. },
  426. contents : [
  427. {
  428. id : 'info',
  429. label : editor.lang.image.infoTab,
  430. accessKey : 'I',
  431. elements :
  432. [
  433. {
  434. type : 'vbox',
  435. padding : 0,
  436. children :
  437. [
  438. {
  439. type : 'hbox',
  440. widths : [ '280px', '110px' ],
  441. align : 'right',
  442. children :
  443. [
  444. {
  445. id : 'txtUrl',
  446. type : 'text',
  447. label : editor.lang.common.url,
  448. required: true,
  449. onChange : function()
  450. {
  451. var dialog = this.getDialog(),
  452. newUrl = this.getValue();
  453. //Update original image
  454. if ( newUrl.length > 0 ) //Prevent from load before onShow
  455. {
  456. dialog = this.getDialog();
  457. var original = dialog.originalElement;
  458. dialog.preview.removeStyle( 'display' );
  459. original.setCustomData( 'isReady', 'false' );
  460. // Show loader
  461. var loader = CKEDITOR.document.getById( imagePreviewLoaderId );
  462. if ( loader )
  463. loader.setStyle( 'display', '' );
  464. original.on( 'load', onImgLoadEvent, dialog );
  465. original.on( 'error', onImgLoadErrorEvent, dialog );
  466. original.on( 'abort', onImgLoadErrorEvent, dialog );
  467. original.setAttribute( 'src', newUrl );
  468. // Query the preloader to figure out the url impacted by based href.
  469. previewPreloader.setAttribute( 'src', newUrl );
  470. dialog.preview.setAttribute( 'src', previewPreloader.$.src );
  471. updatePreview( dialog );
  472. }
  473. // Dont show preview if no URL given.
  474. else if ( dialog.preview )
  475. {
  476. dialog.preview.removeAttribute( 'src' );
  477. dialog.preview.setStyle( 'display', 'none' );
  478. }
  479. },
  480. setup : function( type, element )
  481. {
  482. if ( type == IMAGE )
  483. {
  484. var url = element.data( 'cke-saved-src' ) || element.getAttribute( 'src' );
  485. var field = this;
  486. this.getDialog().dontResetSize = true;
  487. field.setValue( url ); // And call this.onChange()
  488. // Manually set the initial value.(#4191)
  489. field.setInitValue();
  490. }
  491. },
  492. commit : function( type, element )
  493. {
  494. if ( type == IMAGE && ( this.getValue() || this.isChanged() ) )
  495. {
  496. element.data( 'cke-saved-src', this.getValue() );
  497. element.setAttribute( 'src', this.getValue() );
  498. }
  499. else if ( type == CLEANUP )
  500. {
  501. element.setAttribute( 'src', '' ); // If removeAttribute doesn't work.
  502. element.removeAttribute( 'src' );
  503. }
  504. },
  505. validate : CKEDITOR.dialog.validate.notEmpty( editor.lang.image.urlMissing )
  506. },
  507. {
  508. type : 'button',
  509. id : 'browse',
  510. // v-align with the 'txtUrl' field.
  511. // TODO: We need something better than a fixed size here.
  512. style : 'display:inline-block;margin-top:10px;',
  513. align : 'center',
  514. label : editor.lang.common.browseServer,
  515. hidden : true,
  516. filebrowser : 'info:txtUrl'
  517. }
  518. ]
  519. }
  520. ]
  521. },
  522. {
  523. id : 'txtAlt',
  524. type : 'text',
  525. label : editor.lang.image.alt,
  526. accessKey : 'T',
  527. 'default' : '',
  528. onChange : function()
  529. {
  530. updatePreview( this.getDialog() );
  531. },
  532. setup : function( type, element )
  533. {
  534. if ( type == IMAGE )
  535. this.setValue( element.getAttribute( 'alt' ) );
  536. },
  537. commit : function( type, element )
  538. {
  539. if ( type == IMAGE )
  540. {
  541. if ( this.getValue() || this.isChanged() )
  542. element.setAttribute( 'alt', this.getValue() );
  543. }
  544. else if ( type == PREVIEW )
  545. {
  546. element.setAttribute( 'alt', this.getValue() );
  547. }
  548. else if ( type == CLEANUP )
  549. {
  550. element.removeAttribute( 'alt' );
  551. }
  552. }
  553. },
  554. {
  555. type : 'hbox',
  556. children :
  557. [
  558. {
  559. id : 'basic',
  560. type : 'vbox',
  561. children :
  562. [
  563. {
  564. type : 'hbox',
  565. widths : [ '50%', '50%' ],
  566. children :
  567. [
  568. {
  569. type : 'vbox',
  570. padding : 1,
  571. children :
  572. [
  573. {
  574. type : 'text',
  575. width: '40px',
  576. id : 'txtWidth',
  577. label : editor.lang.common.width,
  578. onKeyUp : onSizeChange,
  579. onChange : function()
  580. {
  581. commitInternally.call( this, 'advanced:txtdlgGenStyle' );
  582. },
  583. validate : function()
  584. {
  585. var aMatch = this.getValue().match( regexGetSizeOrEmpty ),
  586. isValid = !!( aMatch && parseInt( aMatch[1], 10 ) !== 0 );
  587. if ( !isValid )
  588. alert( editor.lang.common.invalidWidth );
  589. return isValid;
  590. },
  591. setup : setupDimension,
  592. commit : function( type, element, internalCommit )
  593. {
  594. var value = this.getValue();
  595. if ( type == IMAGE )
  596. {
  597. if ( value )
  598. element.setStyle( 'width', CKEDITOR.tools.cssLength( value ) );
  599. else
  600. element.removeStyle( 'width' );
  601. !internalCommit && element.removeAttribute( 'width' );
  602. }
  603. else if ( type == PREVIEW )
  604. {
  605. var aMatch = value.match( regexGetSize );
  606. if ( !aMatch )
  607. {
  608. var oImageOriginal = this.getDialog().originalElement;
  609. if ( oImageOriginal.getCustomData( 'isReady' ) == 'true' )
  610. element.setStyle( 'width', oImageOriginal.$.width + 'px');
  611. }
  612. else
  613. element.setStyle( 'width', CKEDITOR.tools.cssLength( value ) );
  614. }
  615. else if ( type == CLEANUP )
  616. {
  617. element.removeAttribute( 'width' );
  618. element.removeStyle( 'width' );
  619. }
  620. }
  621. },
  622. {
  623. type : 'text',
  624. id : 'txtHeight',
  625. width: '40px',
  626. label : editor.lang.common.height,
  627. onKeyUp : onSizeChange,
  628. onChange : function()
  629. {
  630. commitInternally.call( this, 'advanced:txtdlgGenStyle' );
  631. },
  632. validate : function()
  633. {
  634. var aMatch = this.getValue().match( regexGetSizeOrEmpty ),
  635. isValid = !!( aMatch && parseInt( aMatch[1], 10 ) !== 0 );
  636. if ( !isValid )
  637. alert( editor.lang.common.invalidHeight );
  638. return isValid;
  639. },
  640. setup : setupDimension,
  641. commit : function( type, element, internalCommit )
  642. {
  643. var value = this.getValue();
  644. if ( type == IMAGE )
  645. {
  646. if ( value )
  647. element.setStyle( 'height', CKEDITOR.tools.cssLength( value ) );
  648. else
  649. element.removeStyle( 'height' );
  650. !internalCommit && element.removeAttribute( 'height' );
  651. }
  652. else if ( type == PREVIEW )
  653. {
  654. var aMatch = value.match( regexGetSize );
  655. if ( !aMatch )
  656. {
  657. var oImageOriginal = this.getDialog().originalElement;
  658. if ( oImageOriginal.getCustomData( 'isReady' ) == 'true' )
  659. element.setStyle( 'height', oImageOriginal.$.height + 'px' );
  660. }
  661. else
  662. element.setStyle( 'height', CKEDITOR.tools.cssLength( value ) );
  663. }
  664. else if ( type == CLEANUP )
  665. {
  666. element.removeAttribute( 'height' );
  667. element.removeStyle( 'height' );
  668. }
  669. }
  670. }
  671. ]
  672. },
  673. {
  674. id : 'ratioLock',
  675. type : 'html',
  676. style : 'margin-top:30px;width:40px;height:40px;',
  677. onLoad : function()
  678. {
  679. // Activate Reset button
  680. var resetButton = CKEDITOR.document.getById( btnResetSizeId ),
  681. ratioButton = CKEDITOR.document.getById( btnLockSizesId );
  682. if ( resetButton )
  683. {
  684. resetButton.on( 'click', function( evt )
  685. {
  686. resetSize( this );
  687. evt.data && evt.data.preventDefault();
  688. }, this.getDialog() );
  689. resetButton.on( 'mouseover', function()
  690. {
  691. this.addClass( 'cke_btn_over' );
  692. }, resetButton );
  693. resetButton.on( 'mouseout', function()
  694. {
  695. this.removeClass( 'cke_btn_over' );
  696. }, resetButton );
  697. }
  698. // Activate (Un)LockRatio button
  699. if ( ratioButton )
  700. {
  701. ratioButton.on( 'click', function(evt)
  702. {
  703. var locked = switchLockRatio( this ),
  704. oImageOriginal = this.originalElement,
  705. width = this.getValueOf( 'info', 'txtWidth' );
  706. if ( oImageOriginal.getCustomData( 'isReady' ) == 'true' && width )
  707. {
  708. var height = oImageOriginal.$.height / oImageOriginal.$.width * width;
  709. if ( !isNaN( height ) )
  710. {
  711. this.setValueOf( 'info', 'txtHeight', Math.round( height ) );
  712. updatePreview( this );
  713. }
  714. }
  715. evt.data && evt.data.preventDefault();
  716. }, this.getDialog() );
  717. ratioButton.on( 'mouseover', function()
  718. {
  719. this.addClass( 'cke_btn_over' );
  720. }, ratioButton );
  721. ratioButton.on( 'mouseout', function()
  722. {
  723. this.removeClass( 'cke_btn_over' );
  724. }, ratioButton );
  725. }
  726. },
  727. html : '<div>'+
  728. '<a href="javascript:void(0)" tabindex="-1" title="' + editor.lang.image.lockRatio +
  729. '" class="cke_btn_locked" id="' + btnLockSizesId + '" role="checkbox"><span class="cke_icon"></span><span class="cke_label">' + editor.lang.image.lockRatio + '</span></a>' +
  730. '<a href="javascript:void(0)" tabindex="-1" title="' + editor.lang.image.resetSize +
  731. '" class="cke_btn_reset" id="' + btnResetSizeId + '" role="button"><span class="cke_label">' + editor.lang.image.resetSize + '</span></a>'+
  732. '</div>'
  733. }
  734. ]
  735. },
  736. {
  737. type : 'vbox',
  738. padding : 1,
  739. children :
  740. [
  741. {
  742. type : 'text',
  743. id : 'txtBorder',
  744. width: '60px',
  745. label : editor.lang.image.border,
  746. 'default' : '',
  747. onKeyUp : function()
  748. {
  749. updatePreview( this.getDialog() );
  750. },
  751. onChange : function()
  752. {
  753. commitInternally.call( this, 'advanced:txtdlgGenStyle' );
  754. },
  755. validate : CKEDITOR.dialog.validate.integer( editor.lang.image.validateBorder ),
  756. setup : function( type, element )
  757. {
  758. if ( type == IMAGE )
  759. {
  760. var value,
  761. borderStyle = element.getStyle( 'border-width' );
  762. borderStyle = borderStyle && borderStyle.match( /^(\d+px)(?: \1 \1 \1)?$/ );
  763. value = borderStyle && parseInt( borderStyle[ 1 ], 10 );
  764. isNaN ( parseInt( value, 10 ) ) && ( value = element.getAttribute( 'border' ) );
  765. this.setValue( value );
  766. }
  767. },
  768. commit : function( type, element, internalCommit )
  769. {
  770. var value = parseInt( this.getValue(), 10 );
  771. if ( type == IMAGE || type == PREVIEW )
  772. {
  773. if ( !isNaN( value ) )
  774. {
  775. element.setStyle( 'border-width', CKEDITOR.tools.cssLength( value ) );
  776. element.setStyle( 'border-style', 'solid' );
  777. }
  778. else if ( !value && this.isChanged() )
  779. {
  780. element.removeStyle( 'border-width' );
  781. element.removeStyle( 'border-style' );
  782. element.removeStyle( 'border-color' );
  783. }
  784. if ( !internalCommit && type == IMAGE )
  785. element.removeAttribute( 'border' );
  786. }
  787. else if ( type == CLEANUP )
  788. {
  789. element.removeAttribute( 'border' );
  790. element.removeStyle( 'border-width' );
  791. element.removeStyle( 'border-style' );
  792. element.removeStyle( 'border-color' );
  793. }
  794. }
  795. },
  796. {
  797. type : 'text',
  798. id : 'txtHSpace',
  799. width: '60px',
  800. label : editor.lang.image.hSpace,
  801. 'default' : '',
  802. onKeyUp : function()
  803. {
  804. updatePreview( this.getDialog() );
  805. },
  806. onChange : function()
  807. {
  808. commitInternally.call( this, 'advanced:txtdlgGenStyle' );
  809. },
  810. validate : CKEDITOR.dialog.validate.integer( editor.lang.image.validateHSpace ),
  811. setup : function( type, element )
  812. {
  813. if ( type == IMAGE )
  814. {
  815. var value,
  816. marginLeftPx,
  817. marginRightPx,
  818. marginLeftStyle = element.getStyle( 'margin-left' ),
  819. marginRightStyle = element.getStyle( 'margin-right' );
  820. marginLeftStyle = marginLeftStyle && marginLeftStyle.match( pxLengthRegex );
  821. marginRightStyle = marginRightStyle && marginRightStyle.match( pxLengthRegex );
  822. marginLeftPx = parseInt( marginLeftStyle, 10 );
  823. marginRightPx = parseInt( marginRightStyle, 10 );
  824. value = ( marginLeftPx == marginRightPx ) && marginLeftPx;
  825. isNaN( parseInt( value, 10 ) ) && ( value = element.getAttribute( 'hspace' ) );
  826. this.setValue( value );
  827. }
  828. },
  829. commit : function( type, element, internalCommit )
  830. {
  831. var value = parseInt( this.getValue(), 10 );
  832. if ( type == IMAGE || type == PREVIEW )
  833. {
  834. if ( !isNaN( value ) )
  835. {
  836. element.setStyle( 'margin-left', CKEDITOR.tools.cssLength( value ) );
  837. element.setStyle( 'margin-right', CKEDITOR.tools.cssLength( value ) );
  838. }
  839. else if ( !value && this.isChanged( ) )
  840. {
  841. element.removeStyle( 'margin-left' );
  842. element.removeStyle( 'margin-right' );
  843. }
  844. if ( !internalCommit && type == IMAGE )
  845. element.removeAttribute( 'hspace' );
  846. }
  847. else if ( type == CLEANUP )
  848. {
  849. element.removeAttribute( 'hspace' );
  850. element.removeStyle( 'margin-left' );
  851. element.removeStyle( 'margin-right' );
  852. }
  853. }
  854. },
  855. {
  856. type : 'text',
  857. id : 'txtVSpace',
  858. width : '60px',
  859. label : editor.lang.image.vSpace,
  860. 'default' : '',
  861. onKeyUp : function()
  862. {
  863. updatePreview( this.getDialog() );
  864. },
  865. onChange : function()
  866. {
  867. commitInternally.call( this, 'advanced:txtdlgGenStyle' );
  868. },
  869. validate : CKEDITOR.dialog.validate.integer( editor.lang.image.validateVSpace ),
  870. setup : function( type, element )
  871. {
  872. if ( type == IMAGE )
  873. {
  874. var value,
  875. marginTopPx,
  876. marginBottomPx,
  877. marginTopStyle = element.getStyle( 'margin-top' ),
  878. marginBottomStyle = element.getStyle( 'margin-bottom' );
  879. marginTopStyle = marginTopStyle && marginTopStyle.match( pxLengthRegex );
  880. marginBottomStyle = marginBottomStyle && marginBottomStyle.match( pxLengthRegex );
  881. marginTopPx = parseInt( marginTopStyle, 10 );
  882. marginBottomPx = parseInt( marginBottomStyle, 10 );
  883. value = ( marginTopPx == marginBottomPx ) && marginTopPx;
  884. isNaN ( parseInt( value, 10 ) ) && ( value = element.getAttribute( 'vspace' ) );
  885. this.setValue( value );
  886. }
  887. },
  888. commit : function( type, element, internalCommit )
  889. {
  890. var value = parseInt( this.getValue(), 10 );
  891. if ( type == IMAGE || type == PREVIEW )
  892. {
  893. if ( !isNaN( value ) )
  894. {
  895. element.setStyle( 'margin-top', CKEDITOR.tools.cssLength( value ) );
  896. element.setStyle( 'margin-bottom', CKEDITOR.tools.cssLength( value ) );
  897. }
  898. else if ( !value && this.isChanged( ) )
  899. {
  900. element.removeStyle( 'margin-top' );
  901. element.removeStyle( 'margin-bottom' );
  902. }
  903. if ( !internalCommit && type == IMAGE )
  904. element.removeAttribute( 'vspace' );
  905. }
  906. else if ( type == CLEANUP )
  907. {
  908. element.removeAttribute( 'vspace' );
  909. element.removeStyle( 'margin-top' );
  910. element.removeStyle( 'margin-bottom' );
  911. }
  912. }
  913. },
  914. {
  915. id : 'cmbAlign',
  916. type : 'select',
  917. widths : [ '35%','65%' ],
  918. style : 'width:90px',
  919. label : editor.lang.common.align,
  920. 'default' : '',
  921. items :
  922. [
  923. [ editor.lang.common.notSet , ''],
  924. [ editor.lang.common.alignLeft , 'left'],
  925. [ editor.lang.common.alignRight , 'right']
  926. // Backward compatible with v2 on setup when specified as attribute value,
  927. // while these values are no more available as select options.
  928. // [ editor.lang.image.alignAbsBottom , 'absBottom'],
  929. // [ editor.lang.image.alignAbsMiddle , 'absMiddle'],
  930. // [ editor.lang.image.alignBaseline , 'baseline'],
  931. // [ editor.lang.image.alignTextTop , 'text-top'],
  932. // [ editor.lang.image.alignBottom , 'bottom'],
  933. // [ editor.lang.image.alignMiddle , 'middle'],
  934. // [ editor.lang.image.alignTop , 'top']
  935. ],
  936. onChange : function()
  937. {
  938. updatePreview( this.getDialog() );
  939. commitInternally.call( this, 'advanced:txtdlgGenStyle' );
  940. },
  941. setup : function( type, element )
  942. {
  943. if ( type == IMAGE )
  944. {
  945. var value = element.getStyle( 'float' );
  946. switch( value )
  947. {
  948. // Ignore those unrelated values.
  949. case 'inherit':
  950. case 'none':
  951. value = '';
  952. }
  953. !value && ( value = ( element.getAttribute( 'align' ) || '' ).toLowerCase() );
  954. this.setValue( value );
  955. }
  956. },
  957. commit : function( type, element, internalCommit )
  958. {
  959. var value = this.getValue();
  960. if ( type == IMAGE || type == PREVIEW )
  961. {
  962. if ( value )
  963. element.setStyle( 'float', value );
  964. else
  965. element.removeStyle( 'float' );
  966. if ( !internalCommit && type == IMAGE )
  967. {
  968. value = ( element.getAttribute( 'align' ) || '' ).toLowerCase();
  969. switch( value )
  970. {
  971. // we should remove it only if it matches "left" or "right",
  972. // otherwise leave it intact.
  973. case 'left':
  974. case 'right':
  975. element.removeAttribute( 'align' );
  976. }
  977. }
  978. }
  979. else if ( type == CLEANUP )
  980. element.removeStyle( 'float' );
  981. }
  982. }
  983. ]
  984. }
  985. ]
  986. },
  987. {
  988. type : 'vbox',
  989. height : '250px',
  990. children :
  991. [
  992. {
  993. type : 'html',
  994. id : 'htmlPreview',
  995. style : 'width:95%;',
  996. html : '<div>' + CKEDITOR.tools.htmlEncode( editor.lang.common.preview ) +'<br>'+
  997. '<div id="' + imagePreviewLoaderId + '" class="ImagePreviewLoader" style="display:none"><div class="loading">&nbsp;</div></div>'+
  998. '<div id="' + imagePreviewBoxId + '" class="ImagePreviewBox"><table><tr><td>'+
  999. '<a href="javascript:void(0)" target="_blank" onclick="return false;" id="' + previewLinkId + '">'+
  1000. '<img id="' + previewImageId + '" alt="" /></a>' +
  1001. ( editor.config.image_previewText ||
  1002. 'Lorem ipsum dolor sit amet, consectetuer adipiscing elit. '+
  1003. 'Maecenas feugiat consequat diam. Maecenas metus. Vivamus diam purus, cursus a, commodo non, facilisis vitae, '+
  1004. '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.' ) +
  1005. '</td></tr></table></div></div>'
  1006. }
  1007. ]
  1008. }
  1009. ]
  1010. }
  1011. ]
  1012. },
  1013. {
  1014. id : 'Link',
  1015. label : editor.lang.link.title,
  1016. padding : 0,
  1017. elements :
  1018. [
  1019. {
  1020. id : 'txtUrl',
  1021. type : 'text',
  1022. label : editor.lang.common.url,
  1023. style : 'width: 100%',
  1024. 'default' : '',
  1025. setup : function( type, element )
  1026. {
  1027. if ( type == LINK )
  1028. {
  1029. var href = element.data( 'cke-saved-href' );
  1030. if ( !href )
  1031. href = element.getAttribute( 'href' );
  1032. this.setValue( href );
  1033. }
  1034. },
  1035. commit : function( type, element )
  1036. {
  1037. if ( type == LINK )
  1038. {
  1039. if ( this.getValue() || this.isChanged() )
  1040. {
  1041. var url = decodeURI( this.getValue() );
  1042. element.data( 'cke-saved-href', url );
  1043. element.setAttribute( 'href', url );
  1044. if ( this.getValue() || !editor.config.image_removeLinkByEmptyURL )
  1045. this.getDialog().addLink = true;
  1046. }
  1047. }
  1048. }
  1049. },
  1050. {
  1051. type : 'button',
  1052. id : 'browse',
  1053. filebrowser :
  1054. {
  1055. action : 'Browse',
  1056. target: 'Link:txtUrl',
  1057. url: editor.config.filebrowserImageBrowseLinkUrl
  1058. },
  1059. style : 'float:right',
  1060. hidden : true,
  1061. label : editor.lang.common.browseServer
  1062. },
  1063. {
  1064. id : 'cmbTarget',
  1065. type : 'select',
  1066. label : editor.lang.common.target,
  1067. 'default' : '',
  1068. items :
  1069. [
  1070. [ editor.lang.common.notSet , ''],
  1071. [ editor.lang.common.targetNew , '_blank'],
  1072. [ editor.lang.common.targetTop , '_top'],
  1073. [ editor.lang.common.targetSelf , '_self'],
  1074. [ editor.lang.common.targetParent , '_parent']
  1075. ],
  1076. setup : function( type, element )
  1077. {
  1078. if ( type == LINK )
  1079. this.setValue( element.getAttribute( 'target' ) || '' );
  1080. },
  1081. commit : function( type, element )
  1082. {
  1083. if ( type == LINK )
  1084. {
  1085. if ( this.getValue() || this.isChanged() )
  1086. element.setAttribute( 'target', this.getValue() );
  1087. }
  1088. }
  1089. }
  1090. ]
  1091. },
  1092. {
  1093. id : 'Upload',
  1094. hidden : true,
  1095. filebrowser : 'uploadButton',
  1096. label : editor.lang.image.upload,
  1097. elements :
  1098. [
  1099. {
  1100. type : 'file',
  1101. id : 'upload',
  1102. label : editor.lang.image.btnUpload,
  1103. style: 'height:40px',
  1104. size : 38
  1105. },
  1106. {
  1107. type : 'fileButton',
  1108. id : 'uploadButton',
  1109. filebrowser : 'info:txtUrl',
  1110. label : editor.lang.image.btnUpload,
  1111. 'for' : [ 'Upload', 'upload' ]
  1112. }
  1113. ]
  1114. },
  1115. {
  1116. id : 'advanced',
  1117. label : editor.lang.common.advancedTab,
  1118. elements :
  1119. [
  1120. {
  1121. type : 'hbox',
  1122. widths : [ '50%', '25%', '25%' ],
  1123. children :
  1124. [
  1125. {
  1126. type : 'text',
  1127. id : 'linkId',
  1128. label : editor.lang.common.id,
  1129. setup : function( type, element )
  1130. {
  1131. if ( type == IMAGE )
  1132. this.setValue( element.getAttribute( 'id' ) );
  1133. },
  1134. commit : function( type, element )
  1135. {
  1136. if ( type == IMAGE )
  1137. {
  1138. if ( this.getValue() || this.isChanged() )
  1139. element.setAttribute( 'id', this.getValue() );
  1140. }
  1141. }
  1142. },
  1143. {
  1144. id : 'cmbLangDir',
  1145. type : 'select',
  1146. style : 'width : 100px;',
  1147. label : editor.lang.common.langDir,
  1148. 'default' : '',
  1149. items :
  1150. [
  1151. [ editor.lang.common.notSet, '' ],
  1152. [ editor.lang.common.langDirLtr, 'ltr' ],
  1153. [ editor.lang.common.langDirRtl, 'rtl' ]
  1154. ],
  1155. setup : function( type, element )
  1156. {
  1157. if ( type == IMAGE )
  1158. this.setValue( element.getAttribute( 'dir' ) );
  1159. },
  1160. commit : function( type, element )
  1161. {
  1162. if ( type == IMAGE )
  1163. {
  1164. if ( this.getValue() || this.isChanged() )
  1165. element.setAttribute( 'dir', this.getValue() );
  1166. }
  1167. }
  1168. },
  1169. {
  1170. type : 'text',
  1171. id : 'txtLangCode',
  1172. label : editor.lang.common.langCode,
  1173. 'default' : '',
  1174. setup : function( type, element )
  1175. {
  1176. if ( type == IMAGE )
  1177. this.setValue( element.getAttribute( 'lang' ) );
  1178. },
  1179. commit : function( type, element )
  1180. {
  1181. if ( type == IMAGE )
  1182. {
  1183. if ( this.getValue() || this.isChanged() )
  1184. element.setAttribute( 'lang', this.getValue() );
  1185. }
  1186. }
  1187. }
  1188. ]
  1189. },
  1190. {
  1191. type : 'text',
  1192. id : 'txtGenLongDescr',
  1193. label : editor.lang.common.longDescr,
  1194. setup : function( type, element )
  1195. {
  1196. if ( type == IMAGE )
  1197. this.setValue( element.getAttribute( 'longDesc' ) );
  1198. },
  1199. commit : function( type, element )
  1200. {
  1201. if ( type == IMAGE )
  1202. {
  1203. if ( this.getValue() || this.isChanged() )
  1204. element.setAttribute( 'longDesc', this.getValue() );
  1205. }
  1206. }
  1207. },
  1208. {
  1209. type : 'hbox',
  1210. widths : [ '50%', '50%' ],
  1211. children :
  1212. [
  1213. {
  1214. type : 'text',
  1215. id : 'txtGenClass',
  1216. label : editor.lang.common.cssClass,
  1217. 'default' : '',
  1218. setup : function( type, element )
  1219. {
  1220. if ( type == IMAGE )
  1221. this.setValue( element.getAttribute( 'class' ) );
  1222. },
  1223. commit : function( type, element )
  1224. {
  1225. if ( type == IMAGE )
  1226. {
  1227. if ( this.getValue() || this.isChanged() )
  1228. element.setAttribute( 'class', this.getValue() );
  1229. }
  1230. }
  1231. },
  1232. {
  1233. type : 'text',
  1234. id : 'txtGenTitle',
  1235. label : editor.lang.common.advisoryTitle,
  1236. 'default' : '',
  1237. onChange : function()
  1238. {
  1239. updatePreview( this.getDialog() );
  1240. },
  1241. setup : function( type, element )
  1242. {
  1243. if ( type == IMAGE )
  1244. this.setValue( element.getAttribute( 'title' ) );
  1245. },
  1246. commit : function( type, element )
  1247. {
  1248. if ( type == IMAGE )
  1249. {
  1250. if ( this.getValue() || this.isChanged() )
  1251. element.setAttribute( 'title', this.getValue() );
  1252. }
  1253. else if ( type == PREVIEW )
  1254. {
  1255. element.setAttribute( 'title', this.getValue() );
  1256. }
  1257. else if ( type == CLEANUP )
  1258. {
  1259. element.removeAttribute( 'title' );
  1260. }
  1261. }
  1262. }
  1263. ]
  1264. },
  1265. {
  1266. type : 'text',
  1267. id : 'txtdlgGenStyle',
  1268. label : editor.lang.common.cssStyle,
  1269. validate : CKEDITOR.dialog.validate.inlineStyle( editor.lang.common.invalidInlineStyle ),
  1270. 'default' : '',
  1271. setup : function( type, element )
  1272. {
  1273. if ( type == IMAGE )
  1274. {
  1275. var genStyle = element.getAttribute( 'style' );
  1276. if ( !genStyle && element.$.style.cssText )
  1277. genStyle = element.$.style.cssText;
  1278. this.setValue( genStyle );
  1279. var height = element.$.style.height,
  1280. width = element.$.style.width,
  1281. aMatchH = ( height ? height : '' ).match( regexGetSize ),
  1282. aMatchW = ( width ? width : '').match( regexGetSize );
  1283. this.attributesInStyle =
  1284. {
  1285. height : !!aMatchH,
  1286. width : !!aMatchW
  1287. };
  1288. }
  1289. },
  1290. onChange : function ()
  1291. {
  1292. commitInternally.call( this,
  1293. [ 'info:cmbFloat', 'info:cmbAlign',
  1294. 'info:txtVSpace', 'info:txtHSpace',
  1295. 'info:txtBorder',
  1296. 'info:txtWidth', 'info:txtHeight' ] );
  1297. updatePreview( this );
  1298. },
  1299. commit : function( type, element )
  1300. {
  1301. if ( type == IMAGE && ( this.getValue() || this.isChanged() ) )
  1302. {
  1303. element.setAttribute( 'style', this.getValue() );
  1304. }
  1305. }
  1306. }
  1307. ]
  1308. }
  1309. ]
  1310. };
  1311. };
  1312. CKEDITOR.dialog.add( 'image', function( editor )
  1313. {
  1314. return imageDialog( editor, 'image' );
  1315. });
  1316. CKEDITOR.dialog.add( 'imagebutton', function( editor )
  1317. {
  1318. return imageDialog( editor, 'imagebutton' );
  1319. });
  1320. })();