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