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