JasonWoof Got questions, comments, patches, etc.? Contact Jason Woofenden
vanilla ckeditor-3.6.1
[ckeditor.git] / _source / plugins / link / dialogs / link.js
1 /*\r
2 Copyright (c) 2003-2011, CKSource - Frederico Knabben. All rights reserved.\r
3 For licensing, see LICENSE.html or http://ckeditor.com/license\r
4 */\r
5 \r
6 CKEDITOR.dialog.add( 'link', function( editor )\r
7 {\r
8         var plugin = CKEDITOR.plugins.link;\r
9         // Handles the event when the "Target" selection box is changed.\r
10         var targetChanged = function()\r
11         {\r
12                 var dialog = this.getDialog(),\r
13                         popupFeatures = dialog.getContentElement( 'target', 'popupFeatures' ),\r
14                         targetName = dialog.getContentElement( 'target', 'linkTargetName' ),\r
15                         value = this.getValue();\r
16 \r
17                 if ( !popupFeatures || !targetName )\r
18                         return;\r
19 \r
20                 popupFeatures = popupFeatures.getElement();\r
21                 popupFeatures.hide();\r
22                 targetName.setValue( '' );\r
23 \r
24                 switch ( value )\r
25                 {\r
26                         case 'frame' :\r
27                                 targetName.setLabel( editor.lang.link.targetFrameName );\r
28                                 targetName.getElement().show();\r
29                                 break;\r
30                         case 'popup' :\r
31                                 popupFeatures.show();\r
32                                 targetName.setLabel( editor.lang.link.targetPopupName );\r
33                                 targetName.getElement().show();\r
34                                 break;\r
35                         default :\r
36                                 targetName.setValue( value );\r
37                                 targetName.getElement().hide();\r
38                                 break;\r
39                 }\r
40 \r
41         };\r
42 \r
43         // Handles the event when the "Type" selection box is changed.\r
44         var linkTypeChanged = function()\r
45         {\r
46                 var dialog = this.getDialog(),\r
47                         partIds = [ 'urlOptions', 'anchorOptions', 'emailOptions' ],\r
48                         typeValue = this.getValue(),\r
49                         uploadTab = dialog.definition.getContents( 'upload' ),\r
50                         uploadInitiallyHidden = uploadTab && uploadTab.hidden;\r
51 \r
52                 if ( typeValue == 'url' )\r
53                 {\r
54                         if ( editor.config.linkShowTargetTab )\r
55                                 dialog.showPage( 'target' );\r
56                         if ( !uploadInitiallyHidden )\r
57                                 dialog.showPage( 'upload' );\r
58                 }\r
59                 else\r
60                 {\r
61                         dialog.hidePage( 'target' );\r
62                         if ( !uploadInitiallyHidden )\r
63                                 dialog.hidePage( 'upload' );\r
64                 }\r
65 \r
66                 for ( var i = 0 ; i < partIds.length ; i++ )\r
67                 {\r
68                         var element = dialog.getContentElement( 'info', partIds[i] );\r
69                         if ( !element )\r
70                                 continue;\r
71 \r
72                         element = element.getElement().getParent().getParent();\r
73                         if ( partIds[i] == typeValue + 'Options' )\r
74                                 element.show();\r
75                         else\r
76                                 element.hide();\r
77                 }\r
78 \r
79                 dialog.layout();\r
80         };\r
81 \r
82         // Loads the parameters in a selected link to the link dialog fields.\r
83         var javascriptProtocolRegex = /^javascript:/,\r
84                 emailRegex = /^mailto:([^?]+)(?:\?(.+))?$/,\r
85                 emailSubjectRegex = /subject=([^;?:@&=$,\/]*)/,\r
86                 emailBodyRegex = /body=([^;?:@&=$,\/]*)/,\r
87                 anchorRegex = /^#(.*)$/,\r
88                 urlRegex = /^((?:http|https|ftp|news):\/\/)?(.*)$/,\r
89                 selectableTargets = /^(_(?:self|top|parent|blank))$/,\r
90                 encodedEmailLinkRegex = /^javascript:void\(location\.href='mailto:'\+String\.fromCharCode\(([^)]+)\)(?:\+'(.*)')?\)$/,\r
91                 functionCallProtectedEmailLinkRegex = /^javascript:([^(]+)\(([^)]+)\)$/;\r
92 \r
93         var popupRegex =\r
94                 /\s*window.open\(\s*this\.href\s*,\s*(?:'([^']*)'|null)\s*,\s*'([^']*)'\s*\)\s*;\s*return\s*false;*\s*/;\r
95         var popupFeaturesRegex = /(?:^|,)([^=]+)=(\d+|yes|no)/gi;\r
96 \r
97         var parseLink = function( editor, element )\r
98         {\r
99                 var href = ( element  && ( element.data( 'cke-saved-href' ) || element.getAttribute( 'href' ) ) ) || '',\r
100                         javascriptMatch,\r
101                         emailMatch,\r
102                         anchorMatch,\r
103                         urlMatch,\r
104                         retval = {};\r
105 \r
106                 if ( ( javascriptMatch = href.match( javascriptProtocolRegex ) ) )\r
107                 {\r
108                         if ( emailProtection == 'encode' )\r
109                         {\r
110                                 href = href.replace( encodedEmailLinkRegex,\r
111                                                 function ( match, protectedAddress, rest )\r
112                                                 {\r
113                                                         return 'mailto:' +\r
114                                                                String.fromCharCode.apply( String, protectedAddress.split( ',' ) ) +\r
115                                                                ( rest && unescapeSingleQuote( rest ) );\r
116                                                 });\r
117                         }\r
118                         // Protected email link as function call.\r
119                         else if ( emailProtection )\r
120                         {\r
121                                 href.replace( functionCallProtectedEmailLinkRegex, function( match, funcName, funcArgs )\r
122                                 {\r
123                                         if ( funcName == compiledProtectionFunction.name )\r
124                                         {\r
125                                                 retval.type = 'email';\r
126                                                 var email = retval.email = {};\r
127 \r
128                                                 var paramRegex = /[^,\s]+/g,\r
129                                                         paramQuoteRegex = /(^')|('$)/g,\r
130                                                         paramsMatch = funcArgs.match( paramRegex ),\r
131                                                         paramsMatchLength = paramsMatch.length,\r
132                                                         paramName,\r
133                                                         paramVal;\r
134 \r
135                                                 for ( var i = 0; i < paramsMatchLength; i++ )\r
136                                                 {\r
137                                                         paramVal = decodeURIComponent( unescapeSingleQuote( paramsMatch[ i ].replace( paramQuoteRegex, '' ) ) );\r
138                                                         paramName = compiledProtectionFunction.params[ i ].toLowerCase();\r
139                                                         email[ paramName ] = paramVal;\r
140                                                 }\r
141                                                 email.address = [ email.name, email.domain ].join( '@' );\r
142                                         }\r
143                                 } );\r
144                         }\r
145                 }\r
146 \r
147                 if ( !retval.type )\r
148                 {\r
149                         if ( ( anchorMatch = href.match( anchorRegex ) ) )\r
150                         {\r
151                                 retval.type = 'anchor';\r
152                                 retval.anchor = {};\r
153                                 retval.anchor.name = retval.anchor.id = anchorMatch[1];\r
154                         }\r
155                         // Protected email link as encoded string.\r
156                         else if ( ( emailMatch = href.match( emailRegex ) ) )\r
157                         {\r
158                                 var subjectMatch = href.match( emailSubjectRegex ),\r
159                                         bodyMatch = href.match( emailBodyRegex );\r
160 \r
161                                 retval.type = 'email';\r
162                                 var email = ( retval.email = {} );\r
163                                 email.address = emailMatch[ 1 ];\r
164                                 subjectMatch && ( email.subject = decodeURIComponent( subjectMatch[ 1 ] ) );\r
165                                 bodyMatch && ( email.body = decodeURIComponent( bodyMatch[ 1 ] ) );\r
166                         }\r
167                         // urlRegex matches empty strings, so need to check for href as well.\r
168                         else if (  href && ( urlMatch = href.match( urlRegex ) ) )\r
169                         {\r
170                                 retval.type = 'url';\r
171                                 retval.url = {};\r
172                                 retval.url.protocol = urlMatch[1];\r
173                                 retval.url.url = urlMatch[2];\r
174                         }\r
175                         else\r
176                                 retval.type = 'url';\r
177                 }\r
178 \r
179                 // Load target and popup settings.\r
180                 if ( element )\r
181                 {\r
182                         var target = element.getAttribute( 'target' );\r
183                         retval.target = {};\r
184                         retval.adv = {};\r
185 \r
186                         // IE BUG: target attribute is an empty string instead of null in IE if it's not set.\r
187                         if ( !target )\r
188                         {\r
189                                 var onclick = element.data( 'cke-pa-onclick' ) || element.getAttribute( 'onclick' ),\r
190                                         onclickMatch = onclick && onclick.match( popupRegex );\r
191                                 if ( onclickMatch )\r
192                                 {\r
193                                         retval.target.type = 'popup';\r
194                                         retval.target.name = onclickMatch[1];\r
195 \r
196                                         var featureMatch;\r
197                                         while ( ( featureMatch = popupFeaturesRegex.exec( onclickMatch[2] ) ) )\r
198                                         {\r
199                                                 // Some values should remain numbers (#7300)\r
200                                                 if ( ( featureMatch[2] == 'yes' || featureMatch[2] == '1' ) && !( featureMatch[1] in { height:1, width:1, top:1, left:1 } ) )\r
201                                                         retval.target[ featureMatch[1] ] = true;\r
202                                                 else if ( isFinite( featureMatch[2] ) )\r
203                                                         retval.target[ featureMatch[1] ] = featureMatch[2];\r
204                                         }\r
205                                 }\r
206                         }\r
207                         else\r
208                         {\r
209                                 var targetMatch = target.match( selectableTargets );\r
210                                 if ( targetMatch )\r
211                                         retval.target.type = retval.target.name = target;\r
212                                 else\r
213                                 {\r
214                                         retval.target.type = 'frame';\r
215                                         retval.target.name = target;\r
216                                 }\r
217                         }\r
218 \r
219                         var me = this;\r
220                         var advAttr = function( inputName, attrName )\r
221                         {\r
222                                 var value = element.getAttribute( attrName );\r
223                                 if ( value !== null )\r
224                                         retval.adv[ inputName ] = value || '';\r
225                         };\r
226                         advAttr( 'advId', 'id' );\r
227                         advAttr( 'advLangDir', 'dir' );\r
228                         advAttr( 'advAccessKey', 'accessKey' );\r
229 \r
230                         retval.adv.advName =\r
231                                 element.data( 'cke-saved-name' )\r
232                                 || element.getAttribute( 'name' )\r
233                                 || '';\r
234                         advAttr( 'advLangCode', 'lang' );\r
235                         advAttr( 'advTabIndex', 'tabindex' );\r
236                         advAttr( 'advTitle', 'title' );\r
237                         advAttr( 'advContentType', 'type' );\r
238                         CKEDITOR.plugins.link.synAnchorSelector ?\r
239                                 retval.adv.advCSSClasses = getLinkClass( element )\r
240                                 : advAttr( 'advCSSClasses', 'class' );\r
241                         advAttr( 'advCharset', 'charset' );\r
242                         advAttr( 'advStyles', 'style' );\r
243                         advAttr( 'advRel', 'rel' );\r
244                 }\r
245 \r
246                 // Find out whether we have any anchors in the editor.\r
247                 var anchors = retval.anchors = [],\r
248                         item;\r
249 \r
250                 // For some browsers we set contenteditable="false" on anchors, making document.anchors not to include them, so we must traverse the links manually (#7893).\r
251                 if ( CKEDITOR.plugins.link.emptyAnchorFix )\r
252                 {\r
253                         var links = editor.document.getElementsByTag( 'a' );\r
254                         for ( i = 0, count = links.count(); i < count; i++ )\r
255                         {\r
256                                 item = links.getItem( i );\r
257                                 if ( item.data( 'cke-saved-name' ) || item.hasAttribute( 'name' ) )\r
258                                         anchors.push( { name : item.data( 'cke-saved-name' ) || item.getAttribute( 'name' ), id : item.getAttribute( 'id' ) } );\r
259                         }\r
260                 }\r
261                 else\r
262                 {\r
263                         var anchorList = new CKEDITOR.dom.nodeList( editor.document.$.anchors );\r
264                         for ( var i = 0, count = anchorList.count(); i < count; i++ )\r
265                         {\r
266                                 item = anchorList.getItem( i );\r
267                                 anchors[ i ] = { name : item.getAttribute( 'name' ), id : item.getAttribute( 'id' ) };\r
268                         }\r
269                 }\r
270 \r
271                 if ( CKEDITOR.plugins.link.fakeAnchor )\r
272                 {\r
273                         var imgs = editor.document.getElementsByTag( 'img' );\r
274                         for ( i = 0, count = imgs.count(); i < count; i++ )\r
275                         {\r
276                                 if ( ( item = CKEDITOR.plugins.link.tryRestoreFakeAnchor( editor, imgs.getItem( i ) ) ) )\r
277                                         anchors.push( { name : item.getAttribute( 'name' ), id : item.getAttribute( 'id' ) } );\r
278                         }\r
279                 }\r
280 \r
281                 // Record down the selected element in the dialog.\r
282                 this._.selectedElement = element;\r
283                 return retval;\r
284         };\r
285 \r
286         var setupParams = function( page, data )\r
287         {\r
288                 if ( data[page] )\r
289                         this.setValue( data[page][this.id] || '' );\r
290         };\r
291 \r
292         var setupPopupParams = function( data )\r
293         {\r
294                 return setupParams.call( this, 'target', data );\r
295         };\r
296 \r
297         var setupAdvParams = function( data )\r
298         {\r
299                 return setupParams.call( this, 'adv', data );\r
300         };\r
301 \r
302         var commitParams = function( page, data )\r
303         {\r
304                 if ( !data[page] )\r
305                         data[page] = {};\r
306 \r
307                 data[page][this.id] = this.getValue() || '';\r
308         };\r
309 \r
310         var commitPopupParams = function( data )\r
311         {\r
312                 return commitParams.call( this, 'target', data );\r
313         };\r
314 \r
315         var commitAdvParams = function( data )\r
316         {\r
317                 return commitParams.call( this, 'adv', data );\r
318         };\r
319 \r
320         function unescapeSingleQuote( str )\r
321         {\r
322                 return str.replace( /\\'/g, '\'' );\r
323         }\r
324 \r
325         function escapeSingleQuote( str )\r
326         {\r
327                 return str.replace( /'/g, '\\$&' );\r
328         }\r
329 \r
330         var emailProtection = editor.config.emailProtection || '';\r
331 \r
332         // Compile the protection function pattern.\r
333         if ( emailProtection && emailProtection != 'encode' )\r
334         {\r
335                 var compiledProtectionFunction = {};\r
336 \r
337                 emailProtection.replace( /^([^(]+)\(([^)]+)\)$/, function( match, funcName, params )\r
338                 {\r
339                         compiledProtectionFunction.name = funcName;\r
340                         compiledProtectionFunction.params = [];\r
341                         params.replace( /[^,\s]+/g, function( param )\r
342                         {\r
343                                 compiledProtectionFunction.params.push( param );\r
344                         } );\r
345                 } );\r
346         }\r
347 \r
348         function protectEmailLinkAsFunction( email )\r
349         {\r
350                 var retval,\r
351                         name = compiledProtectionFunction.name,\r
352                         params = compiledProtectionFunction.params,\r
353                         paramName,\r
354                         paramValue;\r
355 \r
356                 retval = [ name, '(' ];\r
357                 for ( var i = 0; i < params.length; i++ )\r
358                 {\r
359                         paramName = params[ i ].toLowerCase();\r
360                         paramValue = email[ paramName ];\r
361 \r
362                         i > 0 && retval.push( ',' );\r
363                         retval.push( '\'',\r
364                                                  paramValue ?\r
365                                                  escapeSingleQuote( encodeURIComponent( email[ paramName ] ) )\r
366                                                  : '',\r
367                                                  '\'');\r
368                 }\r
369                 retval.push( ')' );\r
370                 return retval.join( '' );\r
371         }\r
372 \r
373         function protectEmailAddressAsEncodedString( address )\r
374         {\r
375                 var charCode,\r
376                         length = address.length,\r
377                         encodedChars = [];\r
378                 for ( var i = 0; i < length; i++ )\r
379                 {\r
380                         charCode = address.charCodeAt( i );\r
381                         encodedChars.push( charCode );\r
382                 }\r
383                 return 'String.fromCharCode(' + encodedChars.join( ',' ) + ')';\r
384         }\r
385 \r
386         function getLinkClass( ele )\r
387         {\r
388                 var className = ele.getAttribute( 'class' );\r
389                 return className ? className.replace( /\s*(?:cke_anchor_empty|cke_anchor)(?:\s*$)?/g, '' ) : '';\r
390         }\r
391 \r
392         var commonLang = editor.lang.common,\r
393                 linkLang = editor.lang.link;\r
394 \r
395         return {\r
396                 title : linkLang.title,\r
397                 minWidth : 350,\r
398                 minHeight : 230,\r
399                 contents : [\r
400                         {\r
401                                 id : 'info',\r
402                                 label : linkLang.info,\r
403                                 title : linkLang.info,\r
404                                 elements :\r
405                                 [\r
406                                         {\r
407                                                 id : 'linkType',\r
408                                                 type : 'select',\r
409                                                 label : linkLang.type,\r
410                                                 'default' : 'url',\r
411                                                 items :\r
412                                                 [\r
413                                                         [ linkLang.toUrl, 'url' ],\r
414                                                         [ linkLang.toAnchor, 'anchor' ],\r
415                                                         [ linkLang.toEmail, 'email' ]\r
416                                                 ],\r
417                                                 onChange : linkTypeChanged,\r
418                                                 setup : function( data )\r
419                                                 {\r
420                                                         if ( data.type )\r
421                                                                 this.setValue( data.type );\r
422                                                 },\r
423                                                 commit : function( data )\r
424                                                 {\r
425                                                         data.type = this.getValue();\r
426                                                 }\r
427                                         },\r
428                                         {\r
429                                                 type : 'vbox',\r
430                                                 id : 'urlOptions',\r
431                                                 children :\r
432                                                 [\r
433                                                         {\r
434                                                                 type : 'hbox',\r
435                                                                 widths : [ '25%', '75%' ],\r
436                                                                 children :\r
437                                                                 [\r
438                                                                         {\r
439                                                                                 id : 'protocol',\r
440                                                                                 type : 'select',\r
441                                                                                 label : commonLang.protocol,\r
442                                                                                 'default' : 'http://',\r
443                                                                                 items :\r
444                                                                                 [\r
445                                                                                         // Force 'ltr' for protocol names in BIDI. (#5433)\r
446                                                                                         [ 'http://\u200E', 'http://' ],\r
447                                                                                         [ 'https://\u200E', 'https://' ],\r
448                                                                                         [ 'ftp://\u200E', 'ftp://' ],\r
449                                                                                         [ 'news://\u200E', 'news://' ],\r
450                                                                                         [ linkLang.other , '' ]\r
451                                                                                 ],\r
452                                                                                 setup : function( data )\r
453                                                                                 {\r
454                                                                                         if ( data.url )\r
455                                                                                                 this.setValue( data.url.protocol || '' );\r
456                                                                                 },\r
457                                                                                 commit : function( data )\r
458                                                                                 {\r
459                                                                                         if ( !data.url )\r
460                                                                                                 data.url = {};\r
461 \r
462                                                                                         data.url.protocol = this.getValue();\r
463                                                                                 }\r
464                                                                         },\r
465                                                                         {\r
466                                                                                 type : 'text',\r
467                                                                                 id : 'url',\r
468                                                                                 label : commonLang.url,\r
469                                                                                 required: true,\r
470                                                                                 onLoad : function ()\r
471                                                                                 {\r
472                                                                                         this.allowOnChange = true;\r
473                                                                                 },\r
474                                                                                 onKeyUp : function()\r
475                                                                                 {\r
476                                                                                         this.allowOnChange = false;\r
477                                                                                         var     protocolCmb = this.getDialog().getContentElement( 'info', 'protocol' ),\r
478                                                                                                 url = this.getValue(),\r
479                                                                                                 urlOnChangeProtocol = /^(http|https|ftp|news):\/\/(?=.)/i,\r
480                                                                                                 urlOnChangeTestOther = /^((javascript:)|[#\/\.\?])/i;\r
481 \r
482                                                                                         var protocol = urlOnChangeProtocol.exec( url );\r
483                                                                                         if ( protocol )\r
484                                                                                         {\r
485                                                                                                 this.setValue( url.substr( protocol[ 0 ].length ) );\r
486                                                                                                 protocolCmb.setValue( protocol[ 0 ].toLowerCase() );\r
487                                                                                         }\r
488                                                                                         else if ( urlOnChangeTestOther.test( url ) )\r
489                                                                                                 protocolCmb.setValue( '' );\r
490 \r
491                                                                                         this.allowOnChange = true;\r
492                                                                                 },\r
493                                                                                 onChange : function()\r
494                                                                                 {\r
495                                                                                         if ( this.allowOnChange )               // Dont't call on dialog load.\r
496                                                                                                 this.onKeyUp();\r
497                                                                                 },\r
498                                                                                 validate : function()\r
499                                                                                 {\r
500                                                                                         var dialog = this.getDialog();\r
501 \r
502                                                                                         if ( dialog.getContentElement( 'info', 'linkType' ) &&\r
503                                                                                                         dialog.getValueOf( 'info', 'linkType' ) != 'url' )\r
504                                                                                                 return true;\r
505 \r
506                                                                                         if ( this.getDialog().fakeObj ) // Edit Anchor.\r
507                                                                                                 return true;\r
508 \r
509                                                                                         var func = CKEDITOR.dialog.validate.notEmpty( linkLang.noUrl );\r
510                                                                                         return func.apply( this );\r
511                                                                                 },\r
512                                                                                 setup : function( data )\r
513                                                                                 {\r
514                                                                                         this.allowOnChange = false;\r
515                                                                                         if ( data.url )\r
516                                                                                                 this.setValue( data.url.url );\r
517                                                                                         this.allowOnChange = true;\r
518 \r
519                                                                                 },\r
520                                                                                 commit : function( data )\r
521                                                                                 {\r
522                                                                                         // IE will not trigger the onChange event if the mouse has been used\r
523                                                                                         // to carry all the operations #4724\r
524                                                                                         this.onChange();\r
525 \r
526                                                                                         if ( !data.url )\r
527                                                                                                 data.url = {};\r
528 \r
529                                                                                         data.url.url = this.getValue();\r
530                                                                                         this.allowOnChange = false;\r
531                                                                                 }\r
532                                                                         }\r
533                                                                 ],\r
534                                                                 setup : function( data )\r
535                                                                 {\r
536                                                                         if ( !this.getDialog().getContentElement( 'info', 'linkType' ) )\r
537                                                                                 this.getElement().show();\r
538                                                                 }\r
539                                                         },\r
540                                                         {\r
541                                                                 type : 'button',\r
542                                                                 id : 'browse',\r
543                                                                 hidden : 'true',\r
544                                                                 filebrowser : 'info:url',\r
545                                                                 label : commonLang.browseServer\r
546                                                         }\r
547                                                 ]\r
548                                         },\r
549                                         {\r
550                                                 type : 'vbox',\r
551                                                 id : 'anchorOptions',\r
552                                                 width : 260,\r
553                                                 align : 'center',\r
554                                                 padding : 0,\r
555                                                 children :\r
556                                                 [\r
557                                                         {\r
558                                                                 type : 'fieldset',\r
559                                                                 id : 'selectAnchorText',\r
560                                                                 label : linkLang.selectAnchor,\r
561                                                                 setup : function( data )\r
562                                                                 {\r
563                                                                         if ( data.anchors.length > 0 )\r
564                                                                                 this.getElement().show();\r
565                                                                         else\r
566                                                                                 this.getElement().hide();\r
567                                                                 },\r
568                                                                 children :\r
569                                                                 [\r
570                                                                         {\r
571                                                                                 type : 'hbox',\r
572                                                                                 id : 'selectAnchor',\r
573                                                                                 children :\r
574                                                                                 [\r
575                                                                                         {\r
576                                                                                                 type : 'select',\r
577                                                                                                 id : 'anchorName',\r
578                                                                                                 'default' : '',\r
579                                                                                                 label : linkLang.anchorName,\r
580                                                                                                 style : 'width: 100%;',\r
581                                                                                                 items :\r
582                                                                                                 [\r
583                                                                                                         [ '' ]\r
584                                                                                                 ],\r
585                                                                                                 setup : function( data )\r
586                                                                                                 {\r
587                                                                                                         this.clear();\r
588                                                                                                         this.add( '' );\r
589                                                                                                         for ( var i = 0 ; i < data.anchors.length ; i++ )\r
590                                                                                                         {\r
591                                                                                                                 if ( data.anchors[i].name )\r
592                                                                                                                         this.add( data.anchors[i].name );\r
593                                                                                                         }\r
594 \r
595                                                                                                         if ( data.anchor )\r
596                                                                                                                 this.setValue( data.anchor.name );\r
597 \r
598                                                                                                         var linkType = this.getDialog().getContentElement( 'info', 'linkType' );\r
599                                                                                                         if ( linkType && linkType.getValue() == 'email' )\r
600                                                                                                                 this.focus();\r
601                                                                                                 },\r
602                                                                                                 commit : function( data )\r
603                                                                                                 {\r
604                                                                                                         if ( !data.anchor )\r
605                                                                                                                 data.anchor = {};\r
606 \r
607                                                                                                         data.anchor.name = this.getValue();\r
608                                                                                                 }\r
609                                                                                         },\r
610                                                                                         {\r
611                                                                                                 type : 'select',\r
612                                                                                                 id : 'anchorId',\r
613                                                                                                 'default' : '',\r
614                                                                                                 label : linkLang.anchorId,\r
615                                                                                                 style : 'width: 100%;',\r
616                                                                                                 items :\r
617                                                                                                 [\r
618                                                                                                         [ '' ]\r
619                                                                                                 ],\r
620                                                                                                 setup : function( data )\r
621                                                                                                 {\r
622                                                                                                         this.clear();\r
623                                                                                                         this.add( '' );\r
624                                                                                                         for ( var i = 0 ; i < data.anchors.length ; i++ )\r
625                                                                                                         {\r
626                                                                                                                 if ( data.anchors[i].id )\r
627                                                                                                                         this.add( data.anchors[i].id );\r
628                                                                                                         }\r
629 \r
630                                                                                                         if ( data.anchor )\r
631                                                                                                                 this.setValue( data.anchor.id );\r
632                                                                                                 },\r
633                                                                                                 commit : function( data )\r
634                                                                                                 {\r
635                                                                                                         if ( !data.anchor )\r
636                                                                                                                 data.anchor = {};\r
637 \r
638                                                                                                         data.anchor.id = this.getValue();\r
639                                                                                                 }\r
640                                                                                         }\r
641                                                                                 ],\r
642                                                                                 setup : function( data )\r
643                                                                                 {\r
644                                                                                         if ( data.anchors.length > 0 )\r
645                                                                                                 this.getElement().show();\r
646                                                                                         else\r
647                                                                                                 this.getElement().hide();\r
648                                                                                 }\r
649                                                                         }\r
650                                                                 ]\r
651                                                         },\r
652                                                         {\r
653                                                                 type : 'html',\r
654                                                                 id : 'noAnchors',\r
655                                                                 style : 'text-align: center;',\r
656                                                                 html : '<div role="label" tabIndex="-1">' + CKEDITOR.tools.htmlEncode( linkLang.noAnchors ) + '</div>',\r
657                                                                 // Focus the first element defined in above html.\r
658                                                                 focus : true,\r
659                                                                 setup : function( data )\r
660                                                                 {\r
661                                                                         if ( data.anchors.length < 1 )\r
662                                                                                 this.getElement().show();\r
663                                                                         else\r
664                                                                                 this.getElement().hide();\r
665                                                                 }\r
666                                                         }\r
667                                                 ],\r
668                                                 setup : function( data )\r
669                                                 {\r
670                                                         if ( !this.getDialog().getContentElement( 'info', 'linkType' ) )\r
671                                                                 this.getElement().hide();\r
672                                                 }\r
673                                         },\r
674                                         {\r
675                                                 type :  'vbox',\r
676                                                 id : 'emailOptions',\r
677                                                 padding : 1,\r
678                                                 children :\r
679                                                 [\r
680                                                         {\r
681                                                                 type : 'text',\r
682                                                                 id : 'emailAddress',\r
683                                                                 label : linkLang.emailAddress,\r
684                                                                 required : true,\r
685                                                                 validate : function()\r
686                                                                 {\r
687                                                                         var dialog = this.getDialog();\r
688 \r
689                                                                         if ( !dialog.getContentElement( 'info', 'linkType' ) ||\r
690                                                                                         dialog.getValueOf( 'info', 'linkType' ) != 'email' )\r
691                                                                                 return true;\r
692 \r
693                                                                         var func = CKEDITOR.dialog.validate.notEmpty( linkLang.noEmail );\r
694                                                                         return func.apply( this );\r
695                                                                 },\r
696                                                                 setup : function( data )\r
697                                                                 {\r
698                                                                         if ( data.email )\r
699                                                                                 this.setValue( data.email.address );\r
700 \r
701                                                                         var linkType = this.getDialog().getContentElement( 'info', 'linkType' );\r
702                                                                         if ( linkType && linkType.getValue() == 'email' )\r
703                                                                                 this.select();\r
704                                                                 },\r
705                                                                 commit : function( data )\r
706                                                                 {\r
707                                                                         if ( !data.email )\r
708                                                                                 data.email = {};\r
709 \r
710                                                                         data.email.address = this.getValue();\r
711                                                                 }\r
712                                                         },\r
713                                                         {\r
714                                                                 type : 'text',\r
715                                                                 id : 'emailSubject',\r
716                                                                 label : linkLang.emailSubject,\r
717                                                                 setup : function( data )\r
718                                                                 {\r
719                                                                         if ( data.email )\r
720                                                                                 this.setValue( data.email.subject );\r
721                                                                 },\r
722                                                                 commit : function( data )\r
723                                                                 {\r
724                                                                         if ( !data.email )\r
725                                                                                 data.email = {};\r
726 \r
727                                                                         data.email.subject = this.getValue();\r
728                                                                 }\r
729                                                         },\r
730                                                         {\r
731                                                                 type : 'textarea',\r
732                                                                 id : 'emailBody',\r
733                                                                 label : linkLang.emailBody,\r
734                                                                 rows : 3,\r
735                                                                 'default' : '',\r
736                                                                 setup : function( data )\r
737                                                                 {\r
738                                                                         if ( data.email )\r
739                                                                                 this.setValue( data.email.body );\r
740                                                                 },\r
741                                                                 commit : function( data )\r
742                                                                 {\r
743                                                                         if ( !data.email )\r
744                                                                                 data.email = {};\r
745 \r
746                                                                         data.email.body = this.getValue();\r
747                                                                 }\r
748                                                         }\r
749                                                 ],\r
750                                                 setup : function( data )\r
751                                                 {\r
752                                                         if ( !this.getDialog().getContentElement( 'info', 'linkType' ) )\r
753                                                                 this.getElement().hide();\r
754                                                 }\r
755                                         }\r
756                                 ]\r
757                         },\r
758                         {\r
759                                 id : 'target',\r
760                                 label : linkLang.target,\r
761                                 title : linkLang.target,\r
762                                 elements :\r
763                                 [\r
764                                         {\r
765                                                 type : 'hbox',\r
766                                                 widths : [ '50%', '50%' ],\r
767                                                 children :\r
768                                                 [\r
769                                                         {\r
770                                                                 type : 'select',\r
771                                                                 id : 'linkTargetType',\r
772                                                                 label : commonLang.target,\r
773                                                                 'default' : 'notSet',\r
774                                                                 style : 'width : 100%;',\r
775                                                                 'items' :\r
776                                                                 [\r
777                                                                         [ commonLang.notSet, 'notSet' ],\r
778                                                                         [ linkLang.targetFrame, 'frame' ],\r
779                                                                         [ linkLang.targetPopup, 'popup' ],\r
780                                                                         [ commonLang.targetNew, '_blank' ],\r
781                                                                         [ commonLang.targetTop, '_top' ],\r
782                                                                         [ commonLang.targetSelf, '_self' ],\r
783                                                                         [ commonLang.targetParent, '_parent' ]\r
784                                                                 ],\r
785                                                                 onChange : targetChanged,\r
786                                                                 setup : function( data )\r
787                                                                 {\r
788                                                                         if ( data.target )\r
789                                                                                 this.setValue( data.target.type || 'notSet' );\r
790                                                                         targetChanged.call( this );\r
791                                                                 },\r
792                                                                 commit : function( data )\r
793                                                                 {\r
794                                                                         if ( !data.target )\r
795                                                                                 data.target = {};\r
796 \r
797                                                                         data.target.type = this.getValue();\r
798                                                                 }\r
799                                                         },\r
800                                                         {\r
801                                                                 type : 'text',\r
802                                                                 id : 'linkTargetName',\r
803                                                                 label : linkLang.targetFrameName,\r
804                                                                 'default' : '',\r
805                                                                 setup : function( data )\r
806                                                                 {\r
807                                                                         if ( data.target )\r
808                                                                                 this.setValue( data.target.name );\r
809                                                                 },\r
810                                                                 commit : function( data )\r
811                                                                 {\r
812                                                                         if ( !data.target )\r
813                                                                                 data.target = {};\r
814 \r
815                                                                         data.target.name = this.getValue().replace(/\W/gi, '');\r
816                                                                 }\r
817                                                         }\r
818                                                 ]\r
819                                         },\r
820                                         {\r
821                                                 type : 'vbox',\r
822                                                 width : '100%',\r
823                                                 align : 'center',\r
824                                                 padding : 2,\r
825                                                 id : 'popupFeatures',\r
826                                                 children :\r
827                                                 [\r
828                                                         {\r
829                                                                 type : 'fieldset',\r
830                                                                 label : linkLang.popupFeatures,\r
831                                                                 children :\r
832                                                                 [\r
833                                                                         {\r
834                                                                                 type : 'hbox',\r
835                                                                                 children :\r
836                                                                                 [\r
837                                                                                         {\r
838                                                                                                 type : 'checkbox',\r
839                                                                                                 id : 'resizable',\r
840                                                                                                 label : linkLang.popupResizable,\r
841                                                                                                 setup : setupPopupParams,\r
842                                                                                                 commit : commitPopupParams\r
843                                                                                         },\r
844                                                                                         {\r
845                                                                                                 type : 'checkbox',\r
846                                                                                                 id : 'status',\r
847                                                                                                 label : linkLang.popupStatusBar,\r
848                                                                                                 setup : setupPopupParams,\r
849                                                                                                 commit : commitPopupParams\r
850 \r
851                                                                                         }\r
852                                                                                 ]\r
853                                                                         },\r
854                                                                         {\r
855                                                                                 type : 'hbox',\r
856                                                                                 children :\r
857                                                                                 [\r
858                                                                                         {\r
859                                                                                                 type : 'checkbox',\r
860                                                                                                 id : 'location',\r
861                                                                                                 label : linkLang.popupLocationBar,\r
862                                                                                                 setup : setupPopupParams,\r
863                                                                                                 commit : commitPopupParams\r
864 \r
865                                                                                         },\r
866                                                                                         {\r
867                                                                                                 type : 'checkbox',\r
868                                                                                                 id : 'toolbar',\r
869                                                                                                 label : linkLang.popupToolbar,\r
870                                                                                                 setup : setupPopupParams,\r
871                                                                                                 commit : commitPopupParams\r
872 \r
873                                                                                         }\r
874                                                                                 ]\r
875                                                                         },\r
876                                                                         {\r
877                                                                                 type : 'hbox',\r
878                                                                                 children :\r
879                                                                                 [\r
880                                                                                         {\r
881                                                                                                 type : 'checkbox',\r
882                                                                                                 id : 'menubar',\r
883                                                                                                 label : linkLang.popupMenuBar,\r
884                                                                                                 setup : setupPopupParams,\r
885                                                                                                 commit : commitPopupParams\r
886 \r
887                                                                                         },\r
888                                                                                         {\r
889                                                                                                 type : 'checkbox',\r
890                                                                                                 id : 'fullscreen',\r
891                                                                                                 label : linkLang.popupFullScreen,\r
892                                                                                                 setup : setupPopupParams,\r
893                                                                                                 commit : commitPopupParams\r
894 \r
895                                                                                         }\r
896                                                                                 ]\r
897                                                                         },\r
898                                                                         {\r
899                                                                                 type : 'hbox',\r
900                                                                                 children :\r
901                                                                                 [\r
902                                                                                         {\r
903                                                                                                 type : 'checkbox',\r
904                                                                                                 id : 'scrollbars',\r
905                                                                                                 label : linkLang.popupScrollBars,\r
906                                                                                                 setup : setupPopupParams,\r
907                                                                                                 commit : commitPopupParams\r
908 \r
909                                                                                         },\r
910                                                                                         {\r
911                                                                                                 type : 'checkbox',\r
912                                                                                                 id : 'dependent',\r
913                                                                                                 label : linkLang.popupDependent,\r
914                                                                                                 setup : setupPopupParams,\r
915                                                                                                 commit : commitPopupParams\r
916 \r
917                                                                                         }\r
918                                                                                 ]\r
919                                                                         },\r
920                                                                         {\r
921                                                                                 type : 'hbox',\r
922                                                                                 children :\r
923                                                                                 [\r
924                                                                                         {\r
925                                                                                                 type :  'text',\r
926                                                                                                 widths : [ '50%', '50%' ],\r
927                                                                                                 labelLayout : 'horizontal',\r
928                                                                                                 label : commonLang.width,\r
929                                                                                                 id : 'width',\r
930                                                                                                 setup : setupPopupParams,\r
931                                                                                                 commit : commitPopupParams\r
932 \r
933                                                                                         },\r
934                                                                                         {\r
935                                                                                                 type :  'text',\r
936                                                                                                 labelLayout : 'horizontal',\r
937                                                                                                 widths : [ '50%', '50%' ],\r
938                                                                                                 label : linkLang.popupLeft,\r
939                                                                                                 id : 'left',\r
940                                                                                                 setup : setupPopupParams,\r
941                                                                                                 commit : commitPopupParams\r
942 \r
943                                                                                         }\r
944                                                                                 ]\r
945                                                                         },\r
946                                                                         {\r
947                                                                                 type : 'hbox',\r
948                                                                                 children :\r
949                                                                                 [\r
950                                                                                         {\r
951                                                                                                 type :  'text',\r
952                                                                                                 labelLayout : 'horizontal',\r
953                                                                                                 widths : [ '50%', '50%' ],\r
954                                                                                                 label : commonLang.height,\r
955                                                                                                 id : 'height',\r
956                                                                                                 setup : setupPopupParams,\r
957                                                                                                 commit : commitPopupParams\r
958 \r
959                                                                                         },\r
960                                                                                         {\r
961                                                                                                 type :  'text',\r
962                                                                                                 labelLayout : 'horizontal',\r
963                                                                                                 label : linkLang.popupTop,\r
964                                                                                                 widths : [ '50%', '50%' ],\r
965                                                                                                 id : 'top',\r
966                                                                                                 setup : setupPopupParams,\r
967                                                                                                 commit : commitPopupParams\r
968 \r
969                                                                                         }\r
970                                                                                 ]\r
971                                                                         }\r
972                                                                 ]\r
973                                                         }\r
974                                                 ]\r
975                                         }\r
976                                 ]\r
977                         },\r
978                         {\r
979                                 id : 'upload',\r
980                                 label : linkLang.upload,\r
981                                 title : linkLang.upload,\r
982                                 hidden : true,\r
983                                 filebrowser : 'uploadButton',\r
984                                 elements :\r
985                                 [\r
986                                         {\r
987                                                 type : 'file',\r
988                                                 id : 'upload',\r
989                                                 label : commonLang.upload,\r
990                                                 style: 'height:40px',\r
991                                                 size : 29\r
992                                         },\r
993                                         {\r
994                                                 type : 'fileButton',\r
995                                                 id : 'uploadButton',\r
996                                                 label : commonLang.uploadSubmit,\r
997                                                 filebrowser : 'info:url',\r
998                                                 'for' : [ 'upload', 'upload' ]\r
999                                         }\r
1000                                 ]\r
1001                         },\r
1002                         {\r
1003                                 id : 'advanced',\r
1004                                 label : linkLang.advanced,\r
1005                                 title : linkLang.advanced,\r
1006                                 elements :\r
1007                                 [\r
1008                                         {\r
1009                                                 type : 'vbox',\r
1010                                                 padding : 1,\r
1011                                                 children :\r
1012                                                 [\r
1013                                                         {\r
1014                                                                 type : 'hbox',\r
1015                                                                 widths : [ '45%', '35%', '20%' ],\r
1016                                                                 children :\r
1017                                                                 [\r
1018                                                                         {\r
1019                                                                                 type : 'text',\r
1020                                                                                 id : 'advId',\r
1021                                                                                 label : linkLang.id,\r
1022                                                                                 setup : setupAdvParams,\r
1023                                                                                 commit : commitAdvParams\r
1024                                                                         },\r
1025                                                                         {\r
1026                                                                                 type : 'select',\r
1027                                                                                 id : 'advLangDir',\r
1028                                                                                 label : linkLang.langDir,\r
1029                                                                                 'default' : '',\r
1030                                                                                 style : 'width:110px',\r
1031                                                                                 items :\r
1032                                                                                 [\r
1033                                                                                         [ commonLang.notSet, '' ],\r
1034                                                                                         [ linkLang.langDirLTR, 'ltr' ],\r
1035                                                                                         [ linkLang.langDirRTL, 'rtl' ]\r
1036                                                                                 ],\r
1037                                                                                 setup : setupAdvParams,\r
1038                                                                                 commit : commitAdvParams\r
1039                                                                         },\r
1040                                                                         {\r
1041                                                                                 type : 'text',\r
1042                                                                                 id : 'advAccessKey',\r
1043                                                                                 width : '80px',\r
1044                                                                                 label : linkLang.acccessKey,\r
1045                                                                                 maxLength : 1,\r
1046                                                                                 setup : setupAdvParams,\r
1047                                                                                 commit : commitAdvParams\r
1048 \r
1049                                                                         }\r
1050                                                                 ]\r
1051                                                         },\r
1052                                                         {\r
1053                                                                 type : 'hbox',\r
1054                                                                 widths : [ '45%', '35%', '20%' ],\r
1055                                                                 children :\r
1056                                                                 [\r
1057                                                                         {\r
1058                                                                                 type : 'text',\r
1059                                                                                 label : linkLang.name,\r
1060                                                                                 id : 'advName',\r
1061                                                                                 setup : setupAdvParams,\r
1062                                                                                 commit : commitAdvParams\r
1063 \r
1064                                                                         },\r
1065                                                                         {\r
1066                                                                                 type : 'text',\r
1067                                                                                 label : linkLang.langCode,\r
1068                                                                                 id : 'advLangCode',\r
1069                                                                                 width : '110px',\r
1070                                                                                 'default' : '',\r
1071                                                                                 setup : setupAdvParams,\r
1072                                                                                 commit : commitAdvParams\r
1073 \r
1074                                                                         },\r
1075                                                                         {\r
1076                                                                                 type : 'text',\r
1077                                                                                 label : linkLang.tabIndex,\r
1078                                                                                 id : 'advTabIndex',\r
1079                                                                                 width : '80px',\r
1080                                                                                 maxLength : 5,\r
1081                                                                                 setup : setupAdvParams,\r
1082                                                                                 commit : commitAdvParams\r
1083 \r
1084                                                                         }\r
1085                                                                 ]\r
1086                                                         }\r
1087                                                 ]\r
1088                                         },\r
1089                                         {\r
1090                                                 type : 'vbox',\r
1091                                                 padding : 1,\r
1092                                                 children :\r
1093                                                 [\r
1094                                                         {\r
1095                                                                 type : 'hbox',\r
1096                                                                 widths : [ '45%', '55%' ],\r
1097                                                                 children :\r
1098                                                                 [\r
1099                                                                         {\r
1100                                                                                 type : 'text',\r
1101                                                                                 label : linkLang.advisoryTitle,\r
1102                                                                                 'default' : '',\r
1103                                                                                 id : 'advTitle',\r
1104                                                                                 setup : setupAdvParams,\r
1105                                                                                 commit : commitAdvParams\r
1106 \r
1107                                                                         },\r
1108                                                                         {\r
1109                                                                                 type : 'text',\r
1110                                                                                 label : linkLang.advisoryContentType,\r
1111                                                                                 'default' : '',\r
1112                                                                                 id : 'advContentType',\r
1113                                                                                 setup : setupAdvParams,\r
1114                                                                                 commit : commitAdvParams\r
1115 \r
1116                                                                         }\r
1117                                                                 ]\r
1118                                                         },\r
1119                                                         {\r
1120                                                                 type : 'hbox',\r
1121                                                                 widths : [ '45%', '55%' ],\r
1122                                                                 children :\r
1123                                                                 [\r
1124                                                                         {\r
1125                                                                                 type : 'text',\r
1126                                                                                 label : linkLang.cssClasses,\r
1127                                                                                 'default' : '',\r
1128                                                                                 id : 'advCSSClasses',\r
1129                                                                                 setup : setupAdvParams,\r
1130                                                                                 commit : commitAdvParams\r
1131 \r
1132                                                                         },\r
1133                                                                         {\r
1134                                                                                 type : 'text',\r
1135                                                                                 label : linkLang.charset,\r
1136                                                                                 'default' : '',\r
1137                                                                                 id : 'advCharset',\r
1138                                                                                 setup : setupAdvParams,\r
1139                                                                                 commit : commitAdvParams\r
1140 \r
1141                                                                         }\r
1142                                                                 ]\r
1143                                                         },\r
1144                                                         {\r
1145                                                                 type : 'hbox',\r
1146                                                                 widths : [ '45%', '55%' ],\r
1147                                                                 children :\r
1148                                                                 [\r
1149                                                                         {\r
1150                                                                                 type : 'text',\r
1151                                                                                 label : linkLang.rel,\r
1152                                                                                 'default' : '',\r
1153                                                                                 id : 'advRel',\r
1154                                                                                 setup : setupAdvParams,\r
1155                                                                                 commit : commitAdvParams\r
1156                                                                         },\r
1157                                                                         {\r
1158                                                                                 type : 'text',\r
1159                                                                                 label : linkLang.styles,\r
1160                                                                                 'default' : '',\r
1161                                                                                 id : 'advStyles',\r
1162                                                                                 setup : setupAdvParams,\r
1163                                                                                 commit : commitAdvParams\r
1164                                                                         }\r
1165                                                                 ]\r
1166                                                         }\r
1167                                                 ]\r
1168                                         }\r
1169                                 ]\r
1170                         }\r
1171                 ],\r
1172                 onShow : function()\r
1173                 {\r
1174                         var editor = this.getParentEditor(),\r
1175                                 selection = editor.getSelection(),\r
1176                                 element = null;\r
1177 \r
1178                         // Fill in all the relevant fields if there's already one link selected.\r
1179                         if ( ( element = plugin.getSelectedLink( editor ) ) && element.hasAttribute( 'href' ) )\r
1180                                 selection.selectElement( element );\r
1181                         else\r
1182                                 element = null;\r
1183 \r
1184                         this.setupContent( parseLink.apply( this, [ editor, element ] ) );\r
1185                 },\r
1186                 onOk : function()\r
1187                 {\r
1188                         var attributes = {},\r
1189                                 removeAttributes = [],\r
1190                                 data = {},\r
1191                                 me = this,\r
1192                                 editor = this.getParentEditor();\r
1193 \r
1194                         this.commitContent( data );\r
1195 \r
1196                         // Compose the URL.\r
1197                         switch ( data.type || 'url' )\r
1198                         {\r
1199                                 case 'url':\r
1200                                         var protocol = ( data.url && data.url.protocol != undefined ) ? data.url.protocol : 'http://',\r
1201                                                 url = ( data.url && CKEDITOR.tools.trim( data.url.url ) ) || '';\r
1202                                         attributes[ 'data-cke-saved-href' ] = ( url.indexOf( '/' ) === 0 ) ? url : protocol + url;\r
1203                                         break;\r
1204                                 case 'anchor':\r
1205                                         var name = ( data.anchor && data.anchor.name ),\r
1206                                                 id = ( data.anchor && data.anchor.id );\r
1207                                         attributes[ 'data-cke-saved-href' ] = '#' + ( name || id || '' );\r
1208                                         break;\r
1209                                 case 'email':\r
1210 \r
1211                                         var linkHref,\r
1212                                                 email = data.email,\r
1213                                                 address = email.address;\r
1214 \r
1215                                         switch( emailProtection )\r
1216                                         {\r
1217                                                 case '' :\r
1218                                                 case 'encode' :\r
1219                                                 {\r
1220                                                         var subject = encodeURIComponent( email.subject || '' ),\r
1221                                                                 body = encodeURIComponent( email.body || '' );\r
1222 \r
1223                                                         // Build the e-mail parameters first.\r
1224                                                         var argList = [];\r
1225                                                         subject && argList.push( 'subject=' + subject );\r
1226                                                         body && argList.push( 'body=' + body );\r
1227                                                         argList = argList.length ? '?' + argList.join( '&' ) : '';\r
1228 \r
1229                                                         if ( emailProtection == 'encode' )\r
1230                                                         {\r
1231                                                                 linkHref = [ 'javascript:void(location.href=\'mailto:\'+',\r
1232                                                                                          protectEmailAddressAsEncodedString( address ) ];\r
1233                                                                 // parameters are optional.\r
1234                                                                 argList && linkHref.push( '+\'', escapeSingleQuote( argList ), '\'' );\r
1235 \r
1236                                                                 linkHref.push( ')' );\r
1237                                                         }\r
1238                                                         else\r
1239                                                                 linkHref = [ 'mailto:', address, argList ];\r
1240 \r
1241                                                         break;\r
1242                                                 }\r
1243                                                 default :\r
1244                                                 {\r
1245                                                         // Separating name and domain.\r
1246                                                         var nameAndDomain = address.split( '@', 2 );\r
1247                                                         email.name = nameAndDomain[ 0 ];\r
1248                                                         email.domain = nameAndDomain[ 1 ];\r
1249 \r
1250                                                         linkHref = [ 'javascript:', protectEmailLinkAsFunction( email ) ];\r
1251                                                 }\r
1252                                         }\r
1253 \r
1254                                         attributes[ 'data-cke-saved-href' ] = linkHref.join( '' );\r
1255                                         break;\r
1256                         }\r
1257 \r
1258                         // Popups and target.\r
1259                         if ( data.target )\r
1260                         {\r
1261                                 if ( data.target.type == 'popup' )\r
1262                                 {\r
1263                                         var onclickList = [ 'window.open(this.href, \'',\r
1264                                                         data.target.name || '', '\', \'' ];\r
1265                                         var featureList = [ 'resizable', 'status', 'location', 'toolbar', 'menubar', 'fullscreen',\r
1266                                                         'scrollbars', 'dependent' ];\r
1267                                         var featureLength = featureList.length;\r
1268                                         var addFeature = function( featureName )\r
1269                                         {\r
1270                                                 if ( data.target[ featureName ] )\r
1271                                                         featureList.push( featureName + '=' + data.target[ featureName ] );\r
1272                                         };\r
1273 \r
1274                                         for ( var i = 0 ; i < featureLength ; i++ )\r
1275                                                 featureList[i] = featureList[i] + ( data.target[ featureList[i] ] ? '=yes' : '=no' ) ;\r
1276                                         addFeature( 'width' );\r
1277                                         addFeature( 'left' );\r
1278                                         addFeature( 'height' );\r
1279                                         addFeature( 'top' );\r
1280 \r
1281                                         onclickList.push( featureList.join( ',' ), '\'); return false;' );\r
1282                                         attributes[ 'data-cke-pa-onclick' ] = onclickList.join( '' );\r
1283 \r
1284                                         // Add the "target" attribute. (#5074)\r
1285                                         removeAttributes.push( 'target' );\r
1286                                 }\r
1287                                 else\r
1288                                 {\r
1289                                         if ( data.target.type != 'notSet' && data.target.name )\r
1290                                                 attributes.target = data.target.name;\r
1291                                         else\r
1292                                                 removeAttributes.push( 'target' );\r
1293 \r
1294                                         removeAttributes.push( 'data-cke-pa-onclick', 'onclick' );\r
1295                                 }\r
1296                         }\r
1297 \r
1298                         // Advanced attributes.\r
1299                         if ( data.adv )\r
1300                         {\r
1301                                 var advAttr = function( inputName, attrName )\r
1302                                 {\r
1303                                         var value = data.adv[ inputName ];\r
1304                                         if ( value )\r
1305                                                 attributes[attrName] = value;\r
1306                                         else\r
1307                                                 removeAttributes.push( attrName );\r
1308                                 };\r
1309 \r
1310                                 advAttr( 'advId', 'id' );\r
1311                                 advAttr( 'advLangDir', 'dir' );\r
1312                                 advAttr( 'advAccessKey', 'accessKey' );\r
1313 \r
1314                                 if ( data.adv[ 'advName' ] )\r
1315                                         attributes[ 'name' ] = attributes[ 'data-cke-saved-name' ] = data.adv[ 'advName' ];\r
1316                                 else\r
1317                                         removeAttributes = removeAttributes.concat( [ 'data-cke-saved-name', 'name' ] );\r
1318 \r
1319                                 advAttr( 'advLangCode', 'lang' );\r
1320                                 advAttr( 'advTabIndex', 'tabindex' );\r
1321                                 advAttr( 'advTitle', 'title' );\r
1322                                 advAttr( 'advContentType', 'type' );\r
1323                                 advAttr( 'advCSSClasses', 'class' );\r
1324                                 advAttr( 'advCharset', 'charset' );\r
1325                                 advAttr( 'advStyles', 'style' );\r
1326                                 advAttr( 'advRel', 'rel' );\r
1327                         }\r
1328 \r
1329 \r
1330                         // Browser need the "href" fro copy/paste link to work. (#6641)\r
1331                         attributes.href = attributes[ 'data-cke-saved-href' ];\r
1332 \r
1333                         if ( !this._.selectedElement )\r
1334                         {\r
1335                                 // Create element if current selection is collapsed.\r
1336                                 var selection = editor.getSelection(),\r
1337                                         ranges = selection.getRanges( true );\r
1338                                 if ( ranges.length == 1 && ranges[0].collapsed )\r
1339                                 {\r
1340                                         // Short mailto link text view (#5736).\r
1341                                         var text = new CKEDITOR.dom.text( data.type == 'email' ?\r
1342                                                         data.email.address : attributes[ 'data-cke-saved-href' ], editor.document );\r
1343                                         ranges[0].insertNode( text );\r
1344                                         ranges[0].selectNodeContents( text );\r
1345                                         selection.selectRanges( ranges );\r
1346                                 }\r
1347 \r
1348                                 // Apply style.\r
1349                                 var style = new CKEDITOR.style( { element : 'a', attributes : attributes } );\r
1350                                 style.type = CKEDITOR.STYLE_INLINE;             // need to override... dunno why.\r
1351                                 style.apply( editor.document );\r
1352                         }\r
1353                         else\r
1354                         {\r
1355                                 // We're only editing an existing link, so just overwrite the attributes.\r
1356                                 var element = this._.selectedElement,\r
1357                                         href = element.data( 'cke-saved-href' ),\r
1358                                         textView = element.getHtml();\r
1359 \r
1360                                 element.setAttributes( attributes );\r
1361                                 element.removeAttributes( removeAttributes );\r
1362 \r
1363                                 if ( data.adv && data.adv.advName && CKEDITOR.plugins.link.synAnchorSelector )\r
1364                                         element.addClass( element.getChildCount() ? 'cke_anchor' : 'cke_anchor_empty' );\r
1365 \r
1366                                 // Update text view when user changes protocol (#4612).\r
1367                                 if ( href == textView || data.type == 'email' && textView.indexOf( '@' ) != -1 )\r
1368                                 {\r
1369                                         // Short mailto link text view (#5736).\r
1370                                         element.setHtml( data.type == 'email' ?\r
1371                                                 data.email.address : attributes[ 'data-cke-saved-href' ] );\r
1372                                 }\r
1373 \r
1374                                 delete this._.selectedElement;\r
1375                         }\r
1376                 },\r
1377                 onLoad : function()\r
1378                 {\r
1379                         if ( !editor.config.linkShowAdvancedTab )\r
1380                                 this.hidePage( 'advanced' );            //Hide Advanded tab.\r
1381 \r
1382                         if ( !editor.config.linkShowTargetTab )\r
1383                                 this.hidePage( 'target' );              //Hide Target tab.\r
1384 \r
1385                 },\r
1386                 // Inital focus on 'url' field if link is of type URL.\r
1387                 onFocus : function()\r
1388                 {\r
1389                         var linkType = this.getContentElement( 'info', 'linkType' ),\r
1390                                         urlField;\r
1391                         if ( linkType && linkType.getValue() == 'url' )\r
1392                         {\r
1393                                 urlField = this.getContentElement( 'info', 'url' );\r
1394                                 urlField.select();\r
1395                         }\r
1396                 }\r
1397         };\r
1398 });\r
1399 \r
1400 /**\r
1401  * The e-mail address anti-spam protection option. The protection will be\r
1402  * applied when creating or modifying e-mail links through the editor interface.<br>\r
1403  * Two methods of protection can be choosed:\r
1404  * <ol> <li>The e-mail parts (name, domain and any other query string) are\r
1405  *                      assembled into a function call pattern. Such function must be\r
1406  *                      provided by the developer in the pages that will use the contents.\r
1407  *              <li>Only the e-mail address is obfuscated into a special string that\r
1408  *                      has no meaning for humans or spam bots, but which is properly\r
1409  *                      rendered and accepted by the browser.</li></ol>\r
1410  * Both approaches require JavaScript to be enabled.\r
1411  * @name CKEDITOR.config.emailProtection\r
1412  * @since 3.1\r
1413  * @type String\r
1414  * @default '' (empty string = disabled)\r
1415  * @example\r
1416  * // href="mailto:tester@ckeditor.com?subject=subject&body=body"\r
1417  * config.emailProtection = '';\r
1418  * @example\r
1419  * // 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
1420  * config.emailProtection = 'encode';\r
1421  * @example\r
1422  * // href="javascript:mt('tester','ckeditor.com','subject','body')"\r
1423  * config.emailProtection = 'mt(NAME,DOMAIN,SUBJECT,BODY)';\r
1424  */\r