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