diff options
Diffstat (limited to 'sources/plugins/link/dialogs/link.js')
-rw-r--r-- | sources/plugins/link/dialogs/link.js | 979 |
1 files changed, 979 insertions, 0 deletions
diff --git a/sources/plugins/link/dialogs/link.js b/sources/plugins/link/dialogs/link.js new file mode 100644 index 0000000..914471f --- /dev/null +++ b/sources/plugins/link/dialogs/link.js | |||
@@ -0,0 +1,979 @@ | |||
1 | /** | ||
2 | * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved. | ||
3 | * For licensing, see LICENSE.md or http://ckeditor.com/license | ||
4 | */ | ||
5 | |||
6 | 'use strict'; | ||
7 | |||
8 | ( function() { | ||
9 | CKEDITOR.dialog.add( 'link', function( editor ) { | ||
10 | var plugin = CKEDITOR.plugins.link, | ||
11 | initialLinkText; | ||
12 | |||
13 | // Handles the event when the "Target" selection box is changed. | ||
14 | var targetChanged = function() { | ||
15 | var dialog = this.getDialog(), | ||
16 | popupFeatures = dialog.getContentElement( 'target', 'popupFeatures' ), | ||
17 | targetName = dialog.getContentElement( 'target', 'linkTargetName' ), | ||
18 | value = this.getValue(); | ||
19 | |||
20 | if ( !popupFeatures || !targetName ) | ||
21 | return; | ||
22 | |||
23 | popupFeatures = popupFeatures.getElement(); | ||
24 | popupFeatures.hide(); | ||
25 | targetName.setValue( '' ); | ||
26 | |||
27 | switch ( value ) { | ||
28 | case 'frame': | ||
29 | targetName.setLabel( editor.lang.link.targetFrameName ); | ||
30 | targetName.getElement().show(); | ||
31 | break; | ||
32 | case 'popup': | ||
33 | popupFeatures.show(); | ||
34 | targetName.setLabel( editor.lang.link.targetPopupName ); | ||
35 | targetName.getElement().show(); | ||
36 | break; | ||
37 | default: | ||
38 | targetName.setValue( value ); | ||
39 | targetName.getElement().hide(); | ||
40 | break; | ||
41 | } | ||
42 | |||
43 | }; | ||
44 | |||
45 | // Handles the event when the "Type" selection box is changed. | ||
46 | var linkTypeChanged = function() { | ||
47 | var dialog = this.getDialog(), | ||
48 | partIds = [ 'urlOptions', 'anchorOptions', 'emailOptions' ], | ||
49 | typeValue = this.getValue(), | ||
50 | uploadTab = dialog.definition.getContents( 'upload' ), | ||
51 | uploadInitiallyHidden = uploadTab && uploadTab.hidden; | ||
52 | |||
53 | if ( typeValue == 'url' ) { | ||
54 | if ( editor.config.linkShowTargetTab ) | ||
55 | dialog.showPage( 'target' ); | ||
56 | if ( !uploadInitiallyHidden ) | ||
57 | dialog.showPage( 'upload' ); | ||
58 | } else { | ||
59 | dialog.hidePage( 'target' ); | ||
60 | if ( !uploadInitiallyHidden ) | ||
61 | dialog.hidePage( 'upload' ); | ||
62 | } | ||
63 | |||
64 | for ( var i = 0; i < partIds.length; i++ ) { | ||
65 | var element = dialog.getContentElement( 'info', partIds[ i ] ); | ||
66 | if ( !element ) | ||
67 | continue; | ||
68 | |||
69 | element = element.getElement().getParent().getParent(); | ||
70 | if ( partIds[ i ] == typeValue + 'Options' ) | ||
71 | element.show(); | ||
72 | else | ||
73 | element.hide(); | ||
74 | } | ||
75 | |||
76 | dialog.layout(); | ||
77 | }; | ||
78 | |||
79 | var setupParams = function( page, data ) { | ||
80 | if ( data[ page ] ) | ||
81 | this.setValue( data[ page ][ this.id ] || '' ); | ||
82 | }; | ||
83 | |||
84 | var setupPopupParams = function( data ) { | ||
85 | return setupParams.call( this, 'target', data ); | ||
86 | }; | ||
87 | |||
88 | var setupAdvParams = function( data ) { | ||
89 | return setupParams.call( this, 'advanced', data ); | ||
90 | }; | ||
91 | |||
92 | var commitParams = function( page, data ) { | ||
93 | if ( !data[ page ] ) | ||
94 | data[ page ] = {}; | ||
95 | |||
96 | data[ page ][ this.id ] = this.getValue() || ''; | ||
97 | }; | ||
98 | |||
99 | var commitPopupParams = function( data ) { | ||
100 | return commitParams.call( this, 'target', data ); | ||
101 | }; | ||
102 | |||
103 | var commitAdvParams = function( data ) { | ||
104 | return commitParams.call( this, 'advanced', data ); | ||
105 | }; | ||
106 | |||
107 | var commonLang = editor.lang.common, | ||
108 | linkLang = editor.lang.link, | ||
109 | anchors; | ||
110 | |||
111 | return { | ||
112 | title: linkLang.title, | ||
113 | minWidth: ( CKEDITOR.skinName || editor.config.skin ) == 'moono-lisa' ? 450 : 350, | ||
114 | minHeight: 240, | ||
115 | contents: [ { | ||
116 | id: 'info', | ||
117 | label: linkLang.info, | ||
118 | title: linkLang.info, | ||
119 | elements: [ { | ||
120 | type: 'text', | ||
121 | id: 'linkDisplayText', | ||
122 | label: linkLang.displayText, | ||
123 | setup: function() { | ||
124 | this.enable(); | ||
125 | |||
126 | this.setValue( editor.getSelection().getSelectedText() ); | ||
127 | |||
128 | // Keep inner text so that it can be compared in commit function. By obtaining value from getData() | ||
129 | // we get value stripped from new line chars which is important when comparing the value later on. | ||
130 | initialLinkText = this.getValue(); | ||
131 | }, | ||
132 | commit: function( data ) { | ||
133 | data.linkText = this.isEnabled() ? this.getValue() : ''; | ||
134 | } | ||
135 | }, | ||
136 | { | ||
137 | id: 'linkType', | ||
138 | type: 'select', | ||
139 | label: linkLang.type, | ||
140 | 'default': 'url', | ||
141 | items: [ | ||
142 | [ linkLang.toUrl, 'url' ], | ||
143 | [ linkLang.toAnchor, 'anchor' ], | ||
144 | [ linkLang.toEmail, 'email' ] | ||
145 | ], | ||
146 | onChange: linkTypeChanged, | ||
147 | setup: function( data ) { | ||
148 | this.setValue( data.type || 'url' ); | ||
149 | }, | ||
150 | commit: function( data ) { | ||
151 | data.type = this.getValue(); | ||
152 | } | ||
153 | }, | ||
154 | { | ||
155 | type: 'vbox', | ||
156 | id: 'urlOptions', | ||
157 | children: [ { | ||
158 | type: 'hbox', | ||
159 | widths: [ '25%', '75%' ], | ||
160 | children: [ { | ||
161 | id: 'protocol', | ||
162 | type: 'select', | ||
163 | label: commonLang.protocol, | ||
164 | 'default': 'http://', | ||
165 | items: [ | ||
166 | // Force 'ltr' for protocol names in BIDI. (#5433) | ||
167 | [ 'http://\u200E', 'http://' ], | ||
168 | [ 'https://\u200E', 'https://' ], | ||
169 | [ 'ftp://\u200E', 'ftp://' ], | ||
170 | [ 'news://\u200E', 'news://' ], | ||
171 | [ linkLang.other, '' ] | ||
172 | ], | ||
173 | setup: function( data ) { | ||
174 | if ( data.url ) | ||
175 | this.setValue( data.url.protocol || '' ); | ||
176 | }, | ||
177 | commit: function( data ) { | ||
178 | if ( !data.url ) | ||
179 | data.url = {}; | ||
180 | |||
181 | data.url.protocol = this.getValue(); | ||
182 | } | ||
183 | }, | ||
184 | { | ||
185 | type: 'text', | ||
186 | id: 'url', | ||
187 | label: commonLang.url, | ||
188 | required: true, | ||
189 | onLoad: function() { | ||
190 | this.allowOnChange = true; | ||
191 | }, | ||
192 | onKeyUp: function() { | ||
193 | this.allowOnChange = false; | ||
194 | var protocolCmb = this.getDialog().getContentElement( 'info', 'protocol' ), | ||
195 | url = this.getValue(), | ||
196 | urlOnChangeProtocol = /^(http|https|ftp|news):\/\/(?=.)/i, | ||
197 | urlOnChangeTestOther = /^((javascript:)|[#\/\.\?])/i; | ||
198 | |||
199 | var protocol = urlOnChangeProtocol.exec( url ); | ||
200 | if ( protocol ) { | ||
201 | this.setValue( url.substr( protocol[ 0 ].length ) ); | ||
202 | protocolCmb.setValue( protocol[ 0 ].toLowerCase() ); | ||
203 | } else if ( urlOnChangeTestOther.test( url ) ) { | ||
204 | protocolCmb.setValue( '' ); | ||
205 | } | ||
206 | |||
207 | this.allowOnChange = true; | ||
208 | }, | ||
209 | onChange: function() { | ||
210 | if ( this.allowOnChange ) // Dont't call on dialog load. | ||
211 | this.onKeyUp(); | ||
212 | }, | ||
213 | validate: function() { | ||
214 | var dialog = this.getDialog(); | ||
215 | |||
216 | if ( dialog.getContentElement( 'info', 'linkType' ) && dialog.getValueOf( 'info', 'linkType' ) != 'url' ) | ||
217 | return true; | ||
218 | |||
219 | if ( !editor.config.linkJavaScriptLinksAllowed && ( /javascript\:/ ).test( this.getValue() ) ) { | ||
220 | alert( commonLang.invalidValue ); // jshint ignore:line | ||
221 | return false; | ||
222 | } | ||
223 | |||
224 | if ( this.getDialog().fakeObj ) // Edit Anchor. | ||
225 | return true; | ||
226 | |||
227 | var func = CKEDITOR.dialog.validate.notEmpty( linkLang.noUrl ); | ||
228 | return func.apply( this ); | ||
229 | }, | ||
230 | setup: function( data ) { | ||
231 | this.allowOnChange = false; | ||
232 | if ( data.url ) | ||
233 | this.setValue( data.url.url ); | ||
234 | this.allowOnChange = true; | ||
235 | |||
236 | }, | ||
237 | commit: function( data ) { | ||
238 | // IE will not trigger the onChange event if the mouse has been used | ||
239 | // to carry all the operations #4724 | ||
240 | this.onChange(); | ||
241 | |||
242 | if ( !data.url ) | ||
243 | data.url = {}; | ||
244 | |||
245 | data.url.url = this.getValue(); | ||
246 | this.allowOnChange = false; | ||
247 | } | ||
248 | } ], | ||
249 | setup: function() { | ||
250 | if ( !this.getDialog().getContentElement( 'info', 'linkType' ) ) | ||
251 | this.getElement().show(); | ||
252 | } | ||
253 | }, | ||
254 | { | ||
255 | type: 'button', | ||
256 | id: 'browse', | ||
257 | hidden: 'true', | ||
258 | filebrowser: 'info:url', | ||
259 | label: commonLang.browseServer | ||
260 | } ] | ||
261 | }, | ||
262 | { | ||
263 | type: 'vbox', | ||
264 | id: 'anchorOptions', | ||
265 | width: 260, | ||
266 | align: 'center', | ||
267 | padding: 0, | ||
268 | children: [ { | ||
269 | type: 'fieldset', | ||
270 | id: 'selectAnchorText', | ||
271 | label: linkLang.selectAnchor, | ||
272 | setup: function() { | ||
273 | anchors = plugin.getEditorAnchors( editor ); | ||
274 | |||
275 | this.getElement()[ anchors && anchors.length ? 'show' : 'hide' ](); | ||
276 | }, | ||
277 | children: [ { | ||
278 | type: 'hbox', | ||
279 | id: 'selectAnchor', | ||
280 | children: [ { | ||
281 | type: 'select', | ||
282 | id: 'anchorName', | ||
283 | 'default': '', | ||
284 | label: linkLang.anchorName, | ||
285 | style: 'width: 100%;', | ||
286 | items: [ | ||
287 | [ '' ] | ||
288 | ], | ||
289 | setup: function( data ) { | ||
290 | this.clear(); | ||
291 | this.add( '' ); | ||
292 | |||
293 | if ( anchors ) { | ||
294 | for ( var i = 0; i < anchors.length; i++ ) { | ||
295 | if ( anchors[ i ].name ) | ||
296 | this.add( anchors[ i ].name ); | ||
297 | } | ||
298 | } | ||
299 | |||
300 | if ( data.anchor ) | ||
301 | this.setValue( data.anchor.name ); | ||
302 | |||
303 | var linkType = this.getDialog().getContentElement( 'info', 'linkType' ); | ||
304 | if ( linkType && linkType.getValue() == 'email' ) | ||
305 | this.focus(); | ||
306 | }, | ||
307 | commit: function( data ) { | ||
308 | if ( !data.anchor ) | ||
309 | data.anchor = {}; | ||
310 | |||
311 | data.anchor.name = this.getValue(); | ||
312 | } | ||
313 | }, | ||
314 | { | ||
315 | type: 'select', | ||
316 | id: 'anchorId', | ||
317 | 'default': '', | ||
318 | label: linkLang.anchorId, | ||
319 | style: 'width: 100%;', | ||
320 | items: [ | ||
321 | [ '' ] | ||
322 | ], | ||
323 | setup: function( data ) { | ||
324 | this.clear(); | ||
325 | this.add( '' ); | ||
326 | |||
327 | if ( anchors ) { | ||
328 | for ( var i = 0; i < anchors.length; i++ ) { | ||
329 | if ( anchors[ i ].id ) | ||
330 | this.add( anchors[ i ].id ); | ||
331 | } | ||
332 | } | ||
333 | |||
334 | if ( data.anchor ) | ||
335 | this.setValue( data.anchor.id ); | ||
336 | }, | ||
337 | commit: function( data ) { | ||
338 | if ( !data.anchor ) | ||
339 | data.anchor = {}; | ||
340 | |||
341 | data.anchor.id = this.getValue(); | ||
342 | } | ||
343 | } ], | ||
344 | setup: function() { | ||
345 | this.getElement()[ anchors && anchors.length ? 'show' : 'hide' ](); | ||
346 | } | ||
347 | } ] | ||
348 | }, | ||
349 | { | ||
350 | type: 'html', | ||
351 | id: 'noAnchors', | ||
352 | style: 'text-align: center;', | ||
353 | html: '<div role="note" tabIndex="-1">' + CKEDITOR.tools.htmlEncode( linkLang.noAnchors ) + '</div>', | ||
354 | // Focus the first element defined in above html. | ||
355 | focus: true, | ||
356 | setup: function() { | ||
357 | this.getElement()[ anchors && anchors.length ? 'hide' : 'show' ](); | ||
358 | } | ||
359 | } ], | ||
360 | setup: function() { | ||
361 | if ( !this.getDialog().getContentElement( 'info', 'linkType' ) ) | ||
362 | this.getElement().hide(); | ||
363 | } | ||
364 | }, | ||
365 | { | ||
366 | type: 'vbox', | ||
367 | id: 'emailOptions', | ||
368 | padding: 1, | ||
369 | children: [ { | ||
370 | type: 'text', | ||
371 | id: 'emailAddress', | ||
372 | label: linkLang.emailAddress, | ||
373 | required: true, | ||
374 | validate: function() { | ||
375 | var dialog = this.getDialog(); | ||
376 | |||
377 | if ( !dialog.getContentElement( 'info', 'linkType' ) || dialog.getValueOf( 'info', 'linkType' ) != 'email' ) | ||
378 | return true; | ||
379 | |||
380 | var func = CKEDITOR.dialog.validate.notEmpty( linkLang.noEmail ); | ||
381 | return func.apply( this ); | ||
382 | }, | ||
383 | setup: function( data ) { | ||
384 | if ( data.email ) | ||
385 | this.setValue( data.email.address ); | ||
386 | |||
387 | var linkType = this.getDialog().getContentElement( 'info', 'linkType' ); | ||
388 | if ( linkType && linkType.getValue() == 'email' ) | ||
389 | this.select(); | ||
390 | }, | ||
391 | commit: function( data ) { | ||
392 | if ( !data.email ) | ||
393 | data.email = {}; | ||
394 | |||
395 | data.email.address = this.getValue(); | ||
396 | } | ||
397 | }, | ||
398 | { | ||
399 | type: 'text', | ||
400 | id: 'emailSubject', | ||
401 | label: linkLang.emailSubject, | ||
402 | setup: function( data ) { | ||
403 | if ( data.email ) | ||
404 | this.setValue( data.email.subject ); | ||
405 | }, | ||
406 | commit: function( data ) { | ||
407 | if ( !data.email ) | ||
408 | data.email = {}; | ||
409 | |||
410 | data.email.subject = this.getValue(); | ||
411 | } | ||
412 | }, | ||
413 | { | ||
414 | type: 'textarea', | ||
415 | id: 'emailBody', | ||
416 | label: linkLang.emailBody, | ||
417 | rows: 3, | ||
418 | 'default': '', | ||
419 | setup: function( data ) { | ||
420 | if ( data.email ) | ||
421 | this.setValue( data.email.body ); | ||
422 | }, | ||
423 | commit: function( data ) { | ||
424 | if ( !data.email ) | ||
425 | data.email = {}; | ||
426 | |||
427 | data.email.body = this.getValue(); | ||
428 | } | ||
429 | } ], | ||
430 | setup: function() { | ||
431 | if ( !this.getDialog().getContentElement( 'info', 'linkType' ) ) | ||
432 | this.getElement().hide(); | ||
433 | } | ||
434 | } ] | ||
435 | }, | ||
436 | { | ||
437 | id: 'target', | ||
438 | requiredContent: 'a[target]', // This is not fully correct, because some target option requires JS. | ||
439 | label: linkLang.target, | ||
440 | title: linkLang.target, | ||
441 | elements: [ { | ||
442 | type: 'hbox', | ||
443 | widths: [ '50%', '50%' ], | ||
444 | children: [ { | ||
445 | type: 'select', | ||
446 | id: 'linkTargetType', | ||
447 | label: commonLang.target, | ||
448 | 'default': 'notSet', | ||
449 | style: 'width : 100%;', | ||
450 | 'items': [ | ||
451 | [ commonLang.notSet, 'notSet' ], | ||
452 | [ linkLang.targetFrame, 'frame' ], | ||
453 | [ linkLang.targetPopup, 'popup' ], | ||
454 | [ commonLang.targetNew, '_blank' ], | ||
455 | [ commonLang.targetTop, '_top' ], | ||
456 | [ commonLang.targetSelf, '_self' ], | ||
457 | [ commonLang.targetParent, '_parent' ] | ||
458 | ], | ||
459 | onChange: targetChanged, | ||
460 | setup: function( data ) { | ||
461 | if ( data.target ) | ||
462 | this.setValue( data.target.type || 'notSet' ); | ||
463 | targetChanged.call( this ); | ||
464 | }, | ||
465 | commit: function( data ) { | ||
466 | if ( !data.target ) | ||
467 | data.target = {}; | ||
468 | |||
469 | data.target.type = this.getValue(); | ||
470 | } | ||
471 | }, | ||
472 | { | ||
473 | type: 'text', | ||
474 | id: 'linkTargetName', | ||
475 | label: linkLang.targetFrameName, | ||
476 | 'default': '', | ||
477 | setup: function( data ) { | ||
478 | if ( data.target ) | ||
479 | this.setValue( data.target.name ); | ||
480 | }, | ||
481 | commit: function( data ) { | ||
482 | if ( !data.target ) | ||
483 | data.target = {}; | ||
484 | |||
485 | data.target.name = this.getValue().replace( /([^\x00-\x7F]|\s)/gi, '' ); | ||
486 | } | ||
487 | } ] | ||
488 | }, | ||
489 | { | ||
490 | type: 'vbox', | ||
491 | width: '100%', | ||
492 | align: 'center', | ||
493 | padding: 2, | ||
494 | id: 'popupFeatures', | ||
495 | children: [ { | ||
496 | type: 'fieldset', | ||
497 | label: linkLang.popupFeatures, | ||
498 | children: [ { | ||
499 | type: 'hbox', | ||
500 | children: [ { | ||
501 | type: 'checkbox', | ||
502 | id: 'resizable', | ||
503 | label: linkLang.popupResizable, | ||
504 | setup: setupPopupParams, | ||
505 | commit: commitPopupParams | ||
506 | }, | ||
507 | { | ||
508 | type: 'checkbox', | ||
509 | id: 'status', | ||
510 | label: linkLang.popupStatusBar, | ||
511 | setup: setupPopupParams, | ||
512 | commit: commitPopupParams | ||
513 | |||
514 | } ] | ||
515 | }, | ||
516 | { | ||
517 | type: 'hbox', | ||
518 | children: [ { | ||
519 | type: 'checkbox', | ||
520 | id: 'location', | ||
521 | label: linkLang.popupLocationBar, | ||
522 | setup: setupPopupParams, | ||
523 | commit: commitPopupParams | ||
524 | |||
525 | }, | ||
526 | { | ||
527 | type: 'checkbox', | ||
528 | id: 'toolbar', | ||
529 | label: linkLang.popupToolbar, | ||
530 | setup: setupPopupParams, | ||
531 | commit: commitPopupParams | ||
532 | |||
533 | } ] | ||
534 | }, | ||
535 | { | ||
536 | type: 'hbox', | ||
537 | children: [ { | ||
538 | type: 'checkbox', | ||
539 | id: 'menubar', | ||
540 | label: linkLang.popupMenuBar, | ||
541 | setup: setupPopupParams, | ||
542 | commit: commitPopupParams | ||
543 | |||
544 | }, | ||
545 | { | ||
546 | type: 'checkbox', | ||
547 | id: 'fullscreen', | ||
548 | label: linkLang.popupFullScreen, | ||
549 | setup: setupPopupParams, | ||
550 | commit: commitPopupParams | ||
551 | |||
552 | } ] | ||
553 | }, | ||
554 | { | ||
555 | type: 'hbox', | ||
556 | children: [ { | ||
557 | type: 'checkbox', | ||
558 | id: 'scrollbars', | ||
559 | label: linkLang.popupScrollBars, | ||
560 | setup: setupPopupParams, | ||
561 | commit: commitPopupParams | ||
562 | |||
563 | }, | ||
564 | { | ||
565 | type: 'checkbox', | ||
566 | id: 'dependent', | ||
567 | label: linkLang.popupDependent, | ||
568 | setup: setupPopupParams, | ||
569 | commit: commitPopupParams | ||
570 | |||
571 | } ] | ||
572 | }, | ||
573 | { | ||
574 | type: 'hbox', | ||
575 | children: [ { | ||
576 | type: 'text', | ||
577 | widths: [ '50%', '50%' ], | ||
578 | labelLayout: 'horizontal', | ||
579 | label: commonLang.width, | ||
580 | id: 'width', | ||
581 | setup: setupPopupParams, | ||
582 | commit: commitPopupParams | ||
583 | |||
584 | }, | ||
585 | { | ||
586 | type: 'text', | ||
587 | labelLayout: 'horizontal', | ||
588 | widths: [ '50%', '50%' ], | ||
589 | label: linkLang.popupLeft, | ||
590 | id: 'left', | ||
591 | setup: setupPopupParams, | ||
592 | commit: commitPopupParams | ||
593 | |||
594 | } ] | ||
595 | }, | ||
596 | { | ||
597 | type: 'hbox', | ||
598 | children: [ { | ||
599 | type: 'text', | ||
600 | labelLayout: 'horizontal', | ||
601 | widths: [ '50%', '50%' ], | ||
602 | label: commonLang.height, | ||
603 | id: 'height', | ||
604 | setup: setupPopupParams, | ||
605 | commit: commitPopupParams | ||
606 | |||
607 | }, | ||
608 | { | ||
609 | type: 'text', | ||
610 | labelLayout: 'horizontal', | ||
611 | label: linkLang.popupTop, | ||
612 | widths: [ '50%', '50%' ], | ||
613 | id: 'top', | ||
614 | setup: setupPopupParams, | ||
615 | commit: commitPopupParams | ||
616 | |||
617 | } ] | ||
618 | } ] | ||
619 | } ] | ||
620 | } ] | ||
621 | }, | ||
622 | { | ||
623 | id: 'upload', | ||
624 | label: linkLang.upload, | ||
625 | title: linkLang.upload, | ||
626 | hidden: true, | ||
627 | filebrowser: 'uploadButton', | ||
628 | elements: [ { | ||
629 | type: 'file', | ||
630 | id: 'upload', | ||
631 | label: commonLang.upload, | ||
632 | style: 'height:40px', | ||
633 | size: 29 | ||
634 | }, | ||
635 | { | ||
636 | type: 'fileButton', | ||
637 | id: 'uploadButton', | ||
638 | label: commonLang.uploadSubmit, | ||
639 | filebrowser: 'info:url', | ||
640 | 'for': [ 'upload', 'upload' ] | ||
641 | } ] | ||
642 | }, | ||
643 | { | ||
644 | id: 'advanced', | ||
645 | label: linkLang.advanced, | ||
646 | title: linkLang.advanced, | ||
647 | elements: [ { | ||
648 | type: 'vbox', | ||
649 | padding: 1, | ||
650 | children: [ { | ||
651 | type: 'hbox', | ||
652 | widths: [ '45%', '35%', '20%' ], | ||
653 | children: [ { | ||
654 | type: 'text', | ||
655 | id: 'advId', | ||
656 | requiredContent: 'a[id]', | ||
657 | label: linkLang.id, | ||
658 | setup: setupAdvParams, | ||
659 | commit: commitAdvParams | ||
660 | }, | ||
661 | { | ||
662 | type: 'select', | ||
663 | id: 'advLangDir', | ||
664 | requiredContent: 'a[dir]', | ||
665 | label: linkLang.langDir, | ||
666 | 'default': '', | ||
667 | style: 'width:110px', | ||
668 | items: [ | ||
669 | [ commonLang.notSet, '' ], | ||
670 | [ linkLang.langDirLTR, 'ltr' ], | ||
671 | [ linkLang.langDirRTL, 'rtl' ] | ||
672 | ], | ||
673 | setup: setupAdvParams, | ||
674 | commit: commitAdvParams | ||
675 | }, | ||
676 | { | ||
677 | type: 'text', | ||
678 | id: 'advAccessKey', | ||
679 | requiredContent: 'a[accesskey]', | ||
680 | width: '80px', | ||
681 | label: linkLang.acccessKey, | ||
682 | maxLength: 1, | ||
683 | setup: setupAdvParams, | ||
684 | commit: commitAdvParams | ||
685 | |||
686 | } ] | ||
687 | }, | ||
688 | { | ||
689 | type: 'hbox', | ||
690 | widths: [ '45%', '35%', '20%' ], | ||
691 | children: [ { | ||
692 | type: 'text', | ||
693 | label: linkLang.name, | ||
694 | id: 'advName', | ||
695 | requiredContent: 'a[name]', | ||
696 | setup: setupAdvParams, | ||
697 | commit: commitAdvParams | ||
698 | |||
699 | }, | ||
700 | { | ||
701 | type: 'text', | ||
702 | label: linkLang.langCode, | ||
703 | id: 'advLangCode', | ||
704 | requiredContent: 'a[lang]', | ||
705 | width: '110px', | ||
706 | 'default': '', | ||
707 | setup: setupAdvParams, | ||
708 | commit: commitAdvParams | ||
709 | |||
710 | }, | ||
711 | { | ||
712 | type: 'text', | ||
713 | label: linkLang.tabIndex, | ||
714 | id: 'advTabIndex', | ||
715 | requiredContent: 'a[tabindex]', | ||
716 | width: '80px', | ||
717 | maxLength: 5, | ||
718 | setup: setupAdvParams, | ||
719 | commit: commitAdvParams | ||
720 | |||
721 | } ] | ||
722 | } ] | ||
723 | }, | ||
724 | { | ||
725 | type: 'vbox', | ||
726 | padding: 1, | ||
727 | children: [ { | ||
728 | type: 'hbox', | ||
729 | widths: [ '45%', '55%' ], | ||
730 | children: [ { | ||
731 | type: 'text', | ||
732 | label: linkLang.advisoryTitle, | ||
733 | requiredContent: 'a[title]', | ||
734 | 'default': '', | ||
735 | id: 'advTitle', | ||
736 | setup: setupAdvParams, | ||
737 | commit: commitAdvParams | ||
738 | |||
739 | }, | ||
740 | { | ||
741 | type: 'text', | ||
742 | label: linkLang.advisoryContentType, | ||
743 | requiredContent: 'a[type]', | ||
744 | 'default': '', | ||
745 | id: 'advContentType', | ||
746 | setup: setupAdvParams, | ||
747 | commit: commitAdvParams | ||
748 | |||
749 | } ] | ||
750 | }, | ||
751 | { | ||
752 | type: 'hbox', | ||
753 | widths: [ '45%', '55%' ], | ||
754 | children: [ { | ||
755 | type: 'text', | ||
756 | label: linkLang.cssClasses, | ||
757 | requiredContent: 'a(cke-xyz)', // Random text like 'xyz' will check if all are allowed. | ||
758 | 'default': '', | ||
759 | id: 'advCSSClasses', | ||
760 | setup: setupAdvParams, | ||
761 | commit: commitAdvParams | ||
762 | |||
763 | }, | ||
764 | { | ||
765 | type: 'text', | ||
766 | label: linkLang.charset, | ||
767 | requiredContent: 'a[charset]', | ||
768 | 'default': '', | ||
769 | id: 'advCharset', | ||
770 | setup: setupAdvParams, | ||
771 | commit: commitAdvParams | ||
772 | |||
773 | } ] | ||
774 | }, | ||
775 | { | ||
776 | type: 'hbox', | ||
777 | widths: [ '45%', '55%' ], | ||
778 | children: [ { | ||
779 | type: 'text', | ||
780 | label: linkLang.rel, | ||
781 | requiredContent: 'a[rel]', | ||
782 | 'default': '', | ||
783 | id: 'advRel', | ||
784 | setup: setupAdvParams, | ||
785 | commit: commitAdvParams | ||
786 | }, | ||
787 | { | ||
788 | type: 'text', | ||
789 | label: linkLang.styles, | ||
790 | requiredContent: 'a{cke-xyz}', // Random text like 'xyz' will check if all are allowed. | ||
791 | 'default': '', | ||
792 | id: 'advStyles', | ||
793 | validate: CKEDITOR.dialog.validate.inlineStyle( editor.lang.common.invalidInlineStyle ), | ||
794 | setup: setupAdvParams, | ||
795 | commit: commitAdvParams | ||
796 | } ] | ||
797 | }, | ||
798 | { | ||
799 | type: 'hbox', | ||
800 | widths: [ '45%', '55%' ], | ||
801 | children: [ { | ||
802 | type: 'checkbox', | ||
803 | id: 'download', | ||
804 | requiredContent: 'a[download]', | ||
805 | label: linkLang.download, | ||
806 | setup: function( data ) { | ||
807 | if ( data.download !== undefined ) | ||
808 | this.setValue( 'checked', 'checked' ); | ||
809 | }, | ||
810 | commit: function( data ) { | ||
811 | if ( this.getValue() ) { | ||
812 | data.download = this.getValue(); | ||
813 | } | ||
814 | } | ||
815 | } ] | ||
816 | } ] | ||
817 | } ] | ||
818 | } ], | ||
819 | onShow: function() { | ||
820 | var editor = this.getParentEditor(), | ||
821 | selection = editor.getSelection(), | ||
822 | selectedElement = selection.getSelectedElement(), | ||
823 | displayTextField = this.getContentElement( 'info', 'linkDisplayText' ).getElement().getParent().getParent(), | ||
824 | element = null; | ||
825 | |||
826 | // Fill in all the relevant fields if there's already one link selected. | ||
827 | if ( ( element = plugin.getSelectedLink( editor ) ) && element.hasAttribute( 'href' ) ) { | ||
828 | // Don't change selection if some element is already selected. | ||
829 | // For example - don't destroy fake selection. | ||
830 | if ( !selectedElement ) { | ||
831 | selection.selectElement( element ); | ||
832 | selectedElement = element; | ||
833 | } | ||
834 | } else { | ||
835 | element = null; | ||
836 | } | ||
837 | |||
838 | // Here we'll decide whether or not we want to show Display Text field. | ||
839 | if ( plugin.showDisplayTextForElement( selectedElement, editor ) ) { | ||
840 | displayTextField.show(); | ||
841 | } else { | ||
842 | displayTextField.hide(); | ||
843 | } | ||
844 | |||
845 | var data = plugin.parseLinkAttributes( editor, element ); | ||
846 | |||
847 | // Record down the selected element in the dialog. | ||
848 | this._.selectedElement = element; | ||
849 | |||
850 | this.setupContent( data ); | ||
851 | }, | ||
852 | onOk: function() { | ||
853 | var data = {}; | ||
854 | |||
855 | // Collect data from fields. | ||
856 | this.commitContent( data ); | ||
857 | |||
858 | var selection = editor.getSelection(), | ||
859 | attributes = plugin.getLinkAttributes( editor, data ), | ||
860 | bm, | ||
861 | nestedLinks; | ||
862 | |||
863 | if ( !this._.selectedElement ) { | ||
864 | var range = selection.getRanges()[ 0 ], | ||
865 | text; | ||
866 | |||
867 | // Use link URL as text with a collapsed cursor. | ||
868 | if ( range.collapsed ) { | ||
869 | // Short mailto link text view (#5736). | ||
870 | text = new CKEDITOR.dom.text( data.linkText || ( data.type == 'email' ? | ||
871 | data.email.address : attributes.set[ 'data-cke-saved-href' ] ), editor.document ); | ||
872 | range.insertNode( text ); | ||
873 | range.selectNodeContents( text ); | ||
874 | } else if ( initialLinkText !== data.linkText ) { | ||
875 | text = new CKEDITOR.dom.text( data.linkText, editor.document ); | ||
876 | |||
877 | // Shrink range to preserve block element. | ||
878 | range.shrink( CKEDITOR.SHRINK_TEXT ); | ||
879 | |||
880 | // Use extractHtmlFromRange to remove markup within the selection. Also this method is a little | ||
881 | // smarter than range#deleteContents as it plays better e.g. with table cells. | ||
882 | editor.editable().extractHtmlFromRange( range ); | ||
883 | |||
884 | range.insertNode( text ); | ||
885 | } | ||
886 | |||
887 | // Editable links nested within current range should be removed, so that the link is applied to whole selection. | ||
888 | nestedLinks = range._find( 'a' ); | ||
889 | |||
890 | for ( var i = 0; i < nestedLinks.length; i++ ) { | ||
891 | nestedLinks[ i ].remove( true ); | ||
892 | } | ||
893 | |||
894 | // Apply style. | ||
895 | var style = new CKEDITOR.style( { | ||
896 | element: 'a', | ||
897 | attributes: attributes.set | ||
898 | } ); | ||
899 | |||
900 | style.type = CKEDITOR.STYLE_INLINE; // need to override... dunno why. | ||
901 | style.applyToRange( range, editor ); | ||
902 | range.select(); | ||
903 | } else { | ||
904 | // We're only editing an existing link, so just overwrite the attributes. | ||
905 | var element = this._.selectedElement, | ||
906 | href = element.data( 'cke-saved-href' ), | ||
907 | textView = element.getHtml(), | ||
908 | newText; | ||
909 | |||
910 | element.setAttributes( attributes.set ); | ||
911 | element.removeAttributes( attributes.removed ); | ||
912 | |||
913 | if ( data.linkText && initialLinkText != data.linkText ) { | ||
914 | // Display text has been changed. | ||
915 | newText = data.linkText; | ||
916 | } else if ( href == textView || data.type == 'email' && textView.indexOf( '@' ) != -1 ) { | ||
917 | // Update text view when user changes protocol (#4612). | ||
918 | // Short mailto link text view (#5736). | ||
919 | newText = data.type == 'email' ? data.email.address : attributes.set[ 'data-cke-saved-href' ]; | ||
920 | } | ||
921 | |||
922 | if ( newText ) { | ||
923 | element.setText( newText ); | ||
924 | // We changed the content, so need to select it again. | ||
925 | selection.selectElement( element ); | ||
926 | } | ||
927 | |||
928 | delete this._.selectedElement; | ||
929 | } | ||
930 | }, | ||
931 | onLoad: function() { | ||
932 | if ( !editor.config.linkShowAdvancedTab ) | ||
933 | this.hidePage( 'advanced' ); //Hide Advanded tab. | ||
934 | |||
935 | if ( !editor.config.linkShowTargetTab ) | ||
936 | this.hidePage( 'target' ); //Hide Target tab. | ||
937 | }, | ||
938 | // Inital focus on 'url' field if link is of type URL. | ||
939 | onFocus: function() { | ||
940 | var linkType = this.getContentElement( 'info', 'linkType' ), | ||
941 | urlField; | ||
942 | |||
943 | if ( linkType && linkType.getValue() == 'url' ) { | ||
944 | urlField = this.getContentElement( 'info', 'url' ); | ||
945 | urlField.select(); | ||
946 | } | ||
947 | } | ||
948 | }; | ||
949 | } ); | ||
950 | } )(); | ||
951 | // jscs:disable maximumLineLength | ||
952 | /** | ||
953 | * The e-mail address anti-spam protection option. The protection will be | ||
954 | * applied when creating or modifying e-mail links through the editor interface. | ||
955 | * | ||
956 | * Two methods of protection can be chosen: | ||
957 | * | ||
958 | * 1. The e-mail parts (name, domain, and any other query string) are | ||
959 | * assembled into a function call pattern. Such function must be | ||
960 | * provided by the developer in the pages that will use the contents. | ||
961 | * 2. Only the e-mail address is obfuscated into a special string that | ||
962 | * has no meaning for humans or spam bots, but which is properly | ||
963 | * rendered and accepted by the browser. | ||
964 | * | ||
965 | * Both approaches require JavaScript to be enabled. | ||
966 | * | ||
967 | * // href="mailto:tester@ckeditor.com?subject=subject&body=body" | ||
968 | * config.emailProtection = ''; | ||
969 | * | ||
970 | * // href="<a href=\"javascript:void(location.href=\'mailto:\'+String.fromCharCode(116,101,115,116,101,114,64,99,107,101,100,105,116,111,114,46,99,111,109)+\'?subject=subject&body=body\')\">e-mail</a>" | ||
971 | * config.emailProtection = 'encode'; | ||
972 | * | ||
973 | * // href="javascript:mt('tester','ckeditor.com','subject','body')" | ||
974 | * config.emailProtection = 'mt(NAME,DOMAIN,SUBJECT,BODY)'; | ||
975 | * | ||
976 | * @since 3.1 | ||
977 | * @cfg {String} [emailProtection='' (empty string = disabled)] | ||
978 | * @member CKEDITOR.config | ||
979 | */ | ||