JasonWoof Got questions, comments, patches, etc.? Contact Jason Woofenden
1e06a6ae554323f31952bceb25c2c1838d8eb630
[ckeditor.git] / _source / plugins / link / dialogs / link.js
1 /*\r
2 Copyright (c) 2003-2009, 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         // Handles the event when the "Target" selection box is changed.\r
9         var targetChanged = function()\r
10         {\r
11                 var dialog = this.getDialog(),\r
12                         popupFeatures = dialog.getContentElement( 'target', 'popupFeatures' ),\r
13                         targetName = dialog.getContentElement( 'target', 'linkTargetName' ),\r
14                         value = this.getValue();\r
15 \r
16                 if ( !popupFeatures || !targetName )\r
17                         return;\r
18 \r
19                 popupFeatures = popupFeatures.getElement();\r
20 \r
21                 if ( value == 'popup' )\r
22                 {\r
23                         popupFeatures.show();\r
24                         targetName.setLabel( editor.lang.link.targetPopupName );\r
25                 }\r
26                 else\r
27                 {\r
28                         popupFeatures.hide();\r
29                         targetName.setLabel( editor.lang.link.targetFrameName );\r
30                         this.getDialog().setValueOf( 'target', 'linkTargetName', value.charAt( 0 ) == '_' ? value : '' );\r
31                 }\r
32         };\r
33 \r
34         // Handles the event when the "Type" selection box is changed.\r
35         var linkTypeChanged = function()\r
36         {\r
37                 var dialog = this.getDialog(),\r
38                         partIds = [ 'urlOptions', 'anchorOptions', 'emailOptions' ],\r
39                         typeValue = this.getValue(),\r
40                         uploadTab = dialog.definition.getContents( 'upload' ),\r
41                         uploadInitiallyHidden = uploadTab && uploadTab.hidden;\r
42 \r
43                 if ( typeValue == 'url' )\r
44                 {\r
45                         if ( editor.config.linkShowTargetTab )\r
46                                 dialog.showPage( 'target' );\r
47                         if ( !uploadInitiallyHidden )\r
48                                 dialog.showPage( 'upload' );\r
49                 }\r
50                 else\r
51                 {\r
52                         dialog.hidePage( 'target' );\r
53                         if ( !uploadInitiallyHidden )\r
54                                 dialog.hidePage( 'upload' );\r
55                 }\r
56 \r
57                 for ( var i = 0 ; i < partIds.length ; i++ )\r
58                 {\r
59                         var element = dialog.getContentElement( 'info', partIds[i] );\r
60                         if ( !element )\r
61                                 continue;\r
62 \r
63                         element = element.getElement().getParent().getParent();\r
64                         if ( partIds[i] == typeValue + 'Options' )\r
65                                 element.show();\r
66                         else\r
67                                 element.hide();\r
68                 }\r
69         };\r
70 \r
71         // Loads the parameters in a selected link to the link dialog fields.\r
72         var emailRegex = /^mailto:([^?]+)(?:\?(.+))?$/,\r
73                 emailSubjectRegex = /subject=([^;?:@&=$,\/]*)/,\r
74                 emailBodyRegex = /body=([^;?:@&=$,\/]*)/,\r
75                 anchorRegex = /^#(.*)$/,\r
76                 urlRegex = /^((?:http|https|ftp|news):\/\/)?(.*)$/,\r
77                 selectableTargets = /^(_(?:self|top|parent|blank))$/;\r
78 \r
79         var popupRegex =\r
80                 /\s*window.open\(\s*this\.href\s*,\s*(?:'([^']*)'|null)\s*,\s*'([^']*)'\s*\)\s*;\s*return\s*false;*\s*/;\r
81         var popupFeaturesRegex = /(?:^|,)([^=]+)=(\d+|yes|no)/gi;\r
82 \r
83         var parseLink = function( editor, element )\r
84         {\r
85                 var href = element ? ( element.getAttribute( '_cke_saved_href' ) || element.getAttribute( 'href' ) ) : '',\r
86                         emailMatch = '',\r
87                         anchorMatch = '',\r
88                         urlMatch = false,\r
89                         retval = {};\r
90 \r
91                 if ( href )\r
92                 {\r
93                         emailMatch = href.match( emailRegex );\r
94                         anchorMatch = href.match( anchorRegex );\r
95                         urlMatch = href.match( urlRegex );\r
96                 }\r
97 \r
98                 // Load the link type and URL.\r
99                 if ( emailMatch )\r
100                 {\r
101                         var subjectMatch = href.match( emailSubjectRegex ),\r
102                                 bodyMatch = href.match( emailBodyRegex );\r
103                         retval.type = 'email';\r
104                         retval.email = {};\r
105                         retval.email.address = emailMatch[1];\r
106                         subjectMatch && ( retval.email.subject = decodeURIComponent( subjectMatch[1] ) );\r
107                         bodyMatch && ( retval.email.body = decodeURIComponent( bodyMatch[1] ) );\r
108                 }\r
109                 else if ( anchorMatch )\r
110                 {\r
111                         retval.type = 'anchor';\r
112                         retval.anchor = {};\r
113                         retval.anchor.name = retval.anchor.id = anchorMatch[1];\r
114                 }\r
115                 else if ( href && urlMatch )            // urlRegex matches empty strings, so need to check for href as well.\r
116                 {\r
117                         retval.type = 'url';\r
118                         retval.url = {};\r
119                         retval.url.protocol = urlMatch[1];\r
120                         retval.url.url = urlMatch[2];\r
121                 }\r
122                 else\r
123                         retval.type = 'url';\r
124 \r
125                 // Load target and popup settings.\r
126                 if ( element )\r
127                 {\r
128                         var target = element.getAttribute( 'target' );\r
129                         retval.target = {};\r
130                         retval.adv = {};\r
131 \r
132                         // IE BUG: target attribute is an empty string instead of null in IE if it's not set.\r
133                         if ( !target )\r
134                         {\r
135                                 var onclick = element.getAttribute( '_cke_pa_onclick' ) || element.getAttribute( 'onclick' ),\r
136                                         onclickMatch = onclick && onclick.match( popupRegex );\r
137                                 if ( onclickMatch )\r
138                                 {\r
139                                         retval.target.type = 'popup';\r
140                                         retval.target.name = onclickMatch[1];\r
141 \r
142                                         var featureMatch;\r
143                                         while ( ( featureMatch = popupFeaturesRegex.exec( onclickMatch[2] ) ) )\r
144                                         {\r
145                                                 if ( featureMatch[2] == 'yes' || featureMatch[2] == '1' )\r
146                                                         retval.target[ featureMatch[1] ] = true;\r
147                                                 else if ( isFinite( featureMatch[2] ) )\r
148                                                         retval.target[ featureMatch[1] ] = featureMatch[2];\r
149                                         }\r
150                                 }\r
151                         }\r
152                         else\r
153                         {\r
154                                 var targetMatch = target.match( selectableTargets );\r
155                                 if ( targetMatch )\r
156                                         retval.target.type = retval.target.name = target;\r
157                                 else\r
158                                 {\r
159                                         retval.target.type = 'frame';\r
160                                         retval.target.name = target;\r
161                                 }\r
162                         }\r
163 \r
164                         var me = this;\r
165                         var advAttr = function( inputName, attrName )\r
166                         {\r
167                                 var value = element.getAttribute( attrName );\r
168                                 if ( value !== null )\r
169                                         retval.adv[ inputName ] = value || '';\r
170                         };\r
171                         advAttr( 'advId', 'id' );\r
172                         advAttr( 'advLangDir', 'dir' );\r
173                         advAttr( 'advAccessKey', 'accessKey' );\r
174                         advAttr( 'advName', 'name' );\r
175                         advAttr( 'advLangCode', 'lang' );\r
176                         advAttr( 'advTabIndex', 'tabindex' );\r
177                         advAttr( 'advTitle', 'title' );\r
178                         advAttr( 'advContentType', 'type' );\r
179                         advAttr( 'advCSSClasses', 'class' );\r
180                         advAttr( 'advCharset', 'charset' );\r
181                         advAttr( 'advStyles', 'style' );\r
182                 }\r
183 \r
184                 // Find out whether we have any anchors in the editor.\r
185                 // Get all IMG elements in CK document.\r
186                 var elements = editor.document.getElementsByTag( 'img' ),\r
187                         realAnchors = new CKEDITOR.dom.nodeList( editor.document.$.anchors ),\r
188                         anchors = retval.anchors = [];\r
189 \r
190                 for( var i = 0; i < elements.count() ; i++ )\r
191                 {\r
192                         var item = elements.getItem( i );\r
193                         if ( item.getAttribute( '_cke_realelement' ) && item.getAttribute( '_cke_real_element_type' ) == 'anchor' )\r
194                         {\r
195                                 anchors.push( editor.restoreRealElement( item ) );\r
196                         }\r
197                 }\r
198 \r
199                 for ( i = 0 ; i < realAnchors.count() ; i++ )\r
200                         anchors.push( realAnchors.getItem( i ) );\r
201 \r
202                 for ( i = 0 ; i < anchors.length ; i++ )\r
203                 {\r
204                         item = anchors[ i ];\r
205                         anchors[ i ] = { name : item.getAttribute( 'name' ), id : item.getAttribute( 'id' ) };\r
206                 }\r
207 \r
208                 // Record down the selected element in the dialog.\r
209                 this._.selectedElement = element;\r
210 \r
211                 return retval;\r
212         };\r
213 \r
214         var setupParams = function( page, data )\r
215         {\r
216                 if ( data[page] )\r
217                         this.setValue( data[page][this.id] || '' );\r
218         };\r
219 \r
220         var setupPopupParams = function( data )\r
221         {\r
222                 return setupParams.call( this, 'target', data );\r
223         };\r
224 \r
225         var setupAdvParams = function( data )\r
226         {\r
227                 return setupParams.call( this, 'adv', data );\r
228         };\r
229 \r
230         var commitParams = function( page, data )\r
231         {\r
232                 if ( !data[page] )\r
233                         data[page] = {};\r
234 \r
235                 data[page][this.id] = this.getValue() || '';\r
236         };\r
237 \r
238         var commitPopupParams = function( data )\r
239         {\r
240                 return commitParams.call( this, 'target', data );\r
241         };\r
242 \r
243         var commitAdvParams = function( data )\r
244         {\r
245                 return commitParams.call( this, 'adv', data );\r
246         };\r
247 \r
248         return {\r
249                 title : editor.lang.link.title,\r
250                 minWidth : 350,\r
251                 minHeight : 230,\r
252                 contents : [\r
253                         {\r
254                                 id : 'info',\r
255                                 label : editor.lang.link.info,\r
256                                 title : editor.lang.link.info,\r
257                                 elements :\r
258                                 [\r
259                                         {\r
260                                                 id : 'linkType',\r
261                                                 type : 'select',\r
262                                                 label : editor.lang.link.type,\r
263                                                 'default' : 'url',\r
264                                                 items :\r
265                                                 [\r
266                                                         [ editor.lang.common.url, 'url' ],\r
267                                                         [ editor.lang.link.toAnchor, 'anchor' ],\r
268                                                         [ editor.lang.link.toEmail, 'email' ]\r
269                                                 ],\r
270                                                 onChange : linkTypeChanged,\r
271                                                 setup : function( data )\r
272                                                 {\r
273                                                         if ( data.type )\r
274                                                                 this.setValue( data.type );\r
275                                                 },\r
276                                                 commit : function( data )\r
277                                                 {\r
278                                                         data.type = this.getValue();\r
279                                                 }\r
280                                         },\r
281                                         {\r
282                                                 type : 'vbox',\r
283                                                 id : 'urlOptions',\r
284                                                 children :\r
285                                                 [\r
286                                                         {\r
287                                                                 type : 'hbox',\r
288                                                                 widths : [ '25%', '75%' ],\r
289                                                                 children :\r
290                                                                 [\r
291                                                                         {\r
292                                                                                 id : 'protocol',\r
293                                                                                 type : 'select',\r
294                                                                                 label : editor.lang.common.protocol,\r
295                                                                                 'default' : 'http://',\r
296                                                                                 style : 'width : 100%;',\r
297                                                                                 items :\r
298                                                                                 [\r
299                                                                                         [ 'http://' ],\r
300                                                                                         [ 'https://' ],\r
301                                                                                         [ 'ftp://' ],\r
302                                                                                         [ 'news://' ],\r
303                                                                                         [ '<other>', '' ]\r
304                                                                                 ],\r
305                                                                                 setup : function( data )\r
306                                                                                 {\r
307                                                                                         if ( data.url )\r
308                                                                                                 this.setValue( data.url.protocol || '' );\r
309                                                                                 },\r
310                                                                                 commit : function( data )\r
311                                                                                 {\r
312                                                                                         if ( !data.url )\r
313                                                                                                 data.url = {};\r
314 \r
315                                                                                         data.url.protocol = this.getValue();\r
316                                                                                 }\r
317                                                                         },\r
318                                                                         {\r
319                                                                                 type : 'text',\r
320                                                                                 id : 'url',\r
321                                                                                 label : editor.lang.common.url,\r
322                                                                                 onLoad : function ()\r
323                                                                                 {\r
324                                                                                         this.allowOnChange = true;\r
325                                                                                 },\r
326                                                                                 onKeyUp : function()\r
327                                                                                 {\r
328                                                                                         this.allowOnChange = false;\r
329                                                                                         var     protocolCmb = this.getDialog().getContentElement( 'info', 'protocol' ),\r
330                                                                                                 url = this.getValue(),\r
331                                                                                                 urlOnChangeProtocol = /^(http|https|ftp|news):\/\/(?=.)/gi,\r
332                                                                                                 urlOnChangeTestOther = /^((javascript:)|[#\/\.])/gi;\r
333 \r
334                                                                                         var protocol = urlOnChangeProtocol.exec( url );\r
335                                                                                         if ( protocol )\r
336                                                                                         {\r
337                                                                                                 this.setValue( url.substr( protocol[ 0 ].length ) );\r
338                                                                                                 protocolCmb.setValue( protocol[ 0 ].toLowerCase() );\r
339                                                                                         }\r
340                                                                                         else if ( urlOnChangeTestOther.test( url ) )\r
341                                                                                                 protocolCmb.setValue( '' );\r
342 \r
343                                                                                         this.allowOnChange = true;\r
344                                                                                 },\r
345                                                                                 onChange : function()\r
346                                                                                 {\r
347                                                                                         if ( this.allowOnChange )               // Dont't call on dialog load.\r
348                                                                                                 this.onKeyUp();\r
349                                                                                 },\r
350                                                                                 validate : function()\r
351                                                                                 {\r
352                                                                                         var dialog = this.getDialog();\r
353 \r
354                                                                                         if ( dialog.getContentElement( 'info', 'linkType' ) &&\r
355                                                                                                         dialog.getValueOf( 'info', 'linkType' ) != 'url' )\r
356                                                                                                 return true;\r
357 \r
358                                                                                         if ( this.getDialog().fakeObj ) // Edit Anchor.\r
359                                                                                                 return true;\r
360 \r
361                                                                                         var func = CKEDITOR.dialog.validate.notEmpty( editor.lang.link.noUrl );\r
362                                                                                         return func.apply( this );\r
363                                                                                 },\r
364                                                                                 setup : function( data )\r
365                                                                                 {\r
366                                                                                         this.allowOnChange = false;\r
367                                                                                         if ( data.url )\r
368                                                                                                 this.setValue( data.url.url );\r
369                                                                                         this.allowOnChange = true;\r
370 \r
371                                                                                         var linkType = this.getDialog().getContentElement( 'info', 'linkType' );\r
372                                                                                         if ( linkType && linkType.getValue() == 'url' )\r
373                                                                                                 this.select();\r
374 \r
375                                                                                 },\r
376                                                                                 commit : function( data )\r
377                                                                                 {\r
378                                                                                         if ( !data.url )\r
379                                                                                                 data.url = {};\r
380 \r
381                                                                                         data.url.url = this.getValue();\r
382                                                                                         this.allowOnChange = false;\r
383                                                                                 }\r
384                                                                         }\r
385                                                                 ],\r
386                                                                 setup : function( data )\r
387                                                                 {\r
388                                                                         if ( !this.getDialog().getContentElement( 'info', 'linkType' ) )\r
389                                                                                 this.getElement().show();\r
390                                                                 }\r
391                                                         },\r
392                                                         {\r
393                                                                 type : 'button',\r
394                                                                 id : 'browse',\r
395                                                                 hidden : 'true',\r
396                                                                 filebrowser : 'info:url',\r
397                                                                 label : editor.lang.common.browseServer\r
398                                                         }\r
399                                                 ]\r
400                                         },\r
401                                         {\r
402                                                 type : 'vbox',\r
403                                                 id : 'anchorOptions',\r
404                                                 width : 260,\r
405                                                 align : 'center',\r
406                                                 padding : 0,\r
407                                                 children :\r
408                                                 [\r
409                                                         {\r
410                                                                 type : 'html',\r
411                                                                 id : 'selectAnchorText',\r
412                                                                 html : CKEDITOR.tools.htmlEncode( editor.lang.link.selectAnchor ),\r
413                                                                 setup : function( data )\r
414                                                                 {\r
415                                                                         if ( data.anchors.length > 0 )\r
416                                                                                 this.getElement().show();\r
417                                                                         else\r
418                                                                                 this.getElement().hide();\r
419                                                                 }\r
420                                                         },\r
421                                                         {\r
422                                                                 type : 'html',\r
423                                                                 id : 'noAnchors',\r
424                                                                 style : 'text-align: center;',\r
425                                                                 html : '<div>' + CKEDITOR.tools.htmlEncode( editor.lang.link.noAnchors ) + '</div>',\r
426                                                                 setup : function( data )\r
427                                                                 {\r
428                                                                         if ( data.anchors.length < 1 )\r
429                                                                                 this.getElement().show();\r
430                                                                         else\r
431                                                                                 this.getElement().hide();\r
432                                                                 }\r
433                                                         },\r
434                                                         {\r
435                                                                 type : 'hbox',\r
436                                                                 id : 'selectAnchor',\r
437                                                                 children :\r
438                                                                 [\r
439                                                                         {\r
440                                                                                 type : 'select',\r
441                                                                                 id : 'anchorName',\r
442                                                                                 'default' : '',\r
443                                                                                 label : editor.lang.link.anchorName,\r
444                                                                                 style : 'width: 100%;',\r
445                                                                                 items :\r
446                                                                                 [\r
447                                                                                         [ '' ]\r
448                                                                                 ],\r
449                                                                                 setup : function( data )\r
450                                                                                 {\r
451                                                                                         this.clear();\r
452                                                                                         this.add( '' );\r
453                                                                                         for ( var i = 0 ; i < data.anchors.length ; i++ )\r
454                                                                                         {\r
455                                                                                                 if ( data.anchors[i].name )\r
456                                                                                                         this.add( data.anchors[i].name );\r
457                                                                                         }\r
458 \r
459                                                                                         if ( data.anchor )\r
460                                                                                                 this.setValue( data.anchor.name );\r
461 \r
462                                                                                         var linkType = this.getDialog().getContentElement( 'info', 'linkType' );\r
463                                                                                         if ( linkType && linkType.getValue() == 'email' )\r
464                                                                                                 this.focus();\r
465                                                                                 },\r
466                                                                                 commit : function( data )\r
467                                                                                 {\r
468                                                                                         if ( !data.anchor )\r
469                                                                                                 data.anchor = {};\r
470 \r
471                                                                                         data.anchor.name = this.getValue();\r
472                                                                                 }\r
473                                                                         },\r
474                                                                         {\r
475                                                                                 type : 'select',\r
476                                                                                 id : 'anchorId',\r
477                                                                                 'default' : '',\r
478                                                                                 label : editor.lang.link.anchorId,\r
479                                                                                 style : 'width: 100%;',\r
480                                                                                 items :\r
481                                                                                 [\r
482                                                                                         [ '' ]\r
483                                                                                 ],\r
484                                                                                 setup : function( data )\r
485                                                                                 {\r
486                                                                                         this.clear();\r
487                                                                                         this.add( '' );\r
488                                                                                         for ( var i = 0 ; i < data.anchors.length ; i++ )\r
489                                                                                         {\r
490                                                                                                 if ( data.anchors[i].id )\r
491                                                                                                         this.add( data.anchors[i].id );\r
492                                                                                         }\r
493 \r
494                                                                                         if ( data.anchor )\r
495                                                                                                 this.setValue( data.anchor.id );\r
496                                                                                 },\r
497                                                                                 commit : function( data )\r
498                                                                                 {\r
499                                                                                         if ( !data.anchor )\r
500                                                                                                 data.anchor = {};\r
501 \r
502                                                                                         data.anchor.id = this.getValue();\r
503                                                                                 }\r
504                                                                         }\r
505                                                                 ],\r
506                                                                 setup : function( data )\r
507                                                                 {\r
508                                                                         if ( data.anchors.length > 0 )\r
509                                                                                 this.getElement().show();\r
510                                                                         else\r
511                                                                                 this.getElement().hide();\r
512                                                                 }\r
513                                                         }\r
514                                                 ],\r
515                                                 setup : function( data )\r
516                                                 {\r
517                                                         if ( !this.getDialog().getContentElement( 'info', 'linkType' ) )\r
518                                                                 this.getElement().hide();\r
519                                                 }\r
520                                         },\r
521                                         {\r
522                                                 type :  'vbox',\r
523                                                 id : 'emailOptions',\r
524                                                 padding : 1,\r
525                                                 children :\r
526                                                 [\r
527                                                         {\r
528                                                                 type : 'text',\r
529                                                                 id : 'emailAddress',\r
530                                                                 label : editor.lang.link.emailAddress,\r
531                                                                 validate : function()\r
532                                                                 {\r
533                                                                         var dialog = this.getDialog();\r
534 \r
535                                                                         if ( !dialog.getContentElement( 'info', 'linkType' ) ||\r
536                                                                                         dialog.getValueOf( 'info', 'linkType' ) != 'email' )\r
537                                                                                 return true;\r
538 \r
539                                                                         var func = CKEDITOR.dialog.validate.notEmpty( editor.lang.link.noEmail );\r
540                                                                         return func.apply( this );\r
541                                                                 },\r
542                                                                 setup : function( data )\r
543                                                                 {\r
544                                                                         if ( data.email )\r
545                                                                                 this.setValue( data.email.address );\r
546 \r
547                                                                         var linkType = this.getDialog().getContentElement( 'info', 'linkType' );\r
548                                                                         if ( linkType && linkType.getValue() == 'email' )\r
549                                                                                 this.select();\r
550                                                                 },\r
551                                                                 commit : function( data )\r
552                                                                 {\r
553                                                                         if ( !data.email )\r
554                                                                                 data.email = {};\r
555 \r
556                                                                         data.email.address = this.getValue();\r
557                                                                 }\r
558                                                         },\r
559                                                         {\r
560                                                                 type : 'text',\r
561                                                                 id : 'emailSubject',\r
562                                                                 label : editor.lang.link.emailSubject,\r
563                                                                 setup : function( data )\r
564                                                                 {\r
565                                                                         if ( data.email )\r
566                                                                                 this.setValue( data.email.subject );\r
567                                                                 },\r
568                                                                 commit : function( data )\r
569                                                                 {\r
570                                                                         if ( !data.email )\r
571                                                                                 data.email = {};\r
572 \r
573                                                                         data.email.subject = this.getValue();\r
574                                                                 }\r
575                                                         },\r
576                                                         {\r
577                                                                 type : 'textarea',\r
578                                                                 id : 'emailBody',\r
579                                                                 label : editor.lang.link.emailBody,\r
580                                                                 rows : 3,\r
581                                                                 'default' : '',\r
582                                                                 setup : function( data )\r
583                                                                 {\r
584                                                                         if ( data.email )\r
585                                                                                 this.setValue( data.email.body );\r
586                                                                 },\r
587                                                                 commit : function( data )\r
588                                                                 {\r
589                                                                         if ( !data.email )\r
590                                                                                 data.email = {};\r
591 \r
592                                                                         data.email.body = this.getValue();\r
593                                                                 }\r
594                                                         }\r
595                                                 ],\r
596                                                 setup : function( data )\r
597                                                 {\r
598                                                         if ( !this.getDialog().getContentElement( 'info', 'linkType' ) )\r
599                                                                 this.getElement().hide();\r
600                                                 }\r
601                                         }\r
602                                 ]\r
603                         },\r
604                         {\r
605                                 id : 'target',\r
606                                 label : editor.lang.link.target,\r
607                                 title : editor.lang.link.target,\r
608                                 elements :\r
609                                 [\r
610                                         {\r
611                                                 type : 'hbox',\r
612                                                 widths : [ '50%', '50%' ],\r
613                                                 children :\r
614                                                 [\r
615                                                         {\r
616                                                                 type : 'select',\r
617                                                                 id : 'linkTargetType',\r
618                                                                 label : editor.lang.link.target,\r
619                                                                 'default' : 'notSet',\r
620                                                                 style : 'width : 100%;',\r
621                                                                 'items' :\r
622                                                                 [\r
623                                                                         [ editor.lang.link.targetNotSet, 'notSet' ],\r
624                                                                         [ editor.lang.link.targetFrame, 'frame' ],\r
625                                                                         [ editor.lang.link.targetPopup, 'popup' ],\r
626                                                                         [ editor.lang.link.targetNew, '_blank' ],\r
627                                                                         [ editor.lang.link.targetTop, '_top' ],\r
628                                                                         [ editor.lang.link.targetSelf, '_self' ],\r
629                                                                         [ editor.lang.link.targetParent, '_parent' ]\r
630                                                                 ],\r
631                                                                 onChange : targetChanged,\r
632                                                                 setup : function( data )\r
633                                                                 {\r
634                                                                         if ( data.target )\r
635                                                                                 this.setValue( data.target.type );\r
636                                                                 },\r
637                                                                 commit : function( data )\r
638                                                                 {\r
639                                                                         if ( !data.target )\r
640                                                                                 data.target = {};\r
641 \r
642                                                                         data.target.type = this.getValue();\r
643                                                                 }\r
644                                                         },\r
645                                                         {\r
646                                                                 type : 'text',\r
647                                                                 id : 'linkTargetName',\r
648                                                                 label : editor.lang.link.targetFrameName,\r
649                                                                 'default' : '',\r
650                                                                 setup : function( data )\r
651                                                                 {\r
652                                                                         if ( data.target )\r
653                                                                                 this.setValue( data.target.name );\r
654                                                                 },\r
655                                                                 commit : function( data )\r
656                                                                 {\r
657                                                                         if ( !data.target )\r
658                                                                                 data.target = {};\r
659 \r
660                                                                         data.target.name = this.getValue();\r
661                                                                 }\r
662                                                         }\r
663                                                 ]\r
664                                         },\r
665                                         {\r
666                                                 type : 'vbox',\r
667                                                 width : 260,\r
668                                                 align : 'center',\r
669                                                 padding : 2,\r
670                                                 id : 'popupFeatures',\r
671                                                 children :\r
672                                                 [\r
673                                                         {\r
674                                                                 type : 'html',\r
675                                                                 html : CKEDITOR.tools.htmlEncode( editor.lang.link.popupFeatures )\r
676                                                         },\r
677                                                         {\r
678                                                                 type : 'hbox',\r
679                                                                 children :\r
680                                                                 [\r
681                                                                         {\r
682                                                                                 type : 'checkbox',\r
683                                                                                 id : 'resizable',\r
684                                                                                 label : editor.lang.link.popupResizable,\r
685                                                                                 setup : setupPopupParams,\r
686                                                                                 commit : commitPopupParams\r
687                                                                         },\r
688                                                                         {\r
689                                                                                 type : 'checkbox',\r
690                                                                                 id : 'status',\r
691                                                                                 label : editor.lang.link.popupStatusBar,\r
692                                                                                 setup : setupPopupParams,\r
693                                                                                 commit : commitPopupParams\r
694 \r
695                                                                         }\r
696                                                                 ]\r
697                                                         },\r
698                                                         {\r
699                                                                 type : 'hbox',\r
700                                                                 children :\r
701                                                                 [\r
702                                                                         {\r
703                                                                                 type : 'checkbox',\r
704                                                                                 id : 'location',\r
705                                                                                 label : editor.lang.link.popupLocationBar,\r
706                                                                                 setup : setupPopupParams,\r
707                                                                                 commit : commitPopupParams\r
708 \r
709                                                                         },\r
710                                                                         {\r
711                                                                                 type : 'checkbox',\r
712                                                                                 id : 'toolbar',\r
713                                                                                 label : editor.lang.link.popupToolbar,\r
714                                                                                 setup : setupPopupParams,\r
715                                                                                 commit : commitPopupParams\r
716 \r
717                                                                         }\r
718                                                                 ]\r
719                                                         },\r
720                                                         {\r
721                                                                 type : 'hbox',\r
722                                                                 children :\r
723                                                                 [\r
724                                                                         {\r
725                                                                                 type : 'checkbox',\r
726                                                                                 id : 'menubar',\r
727                                                                                 label : editor.lang.link.popupMenuBar,\r
728                                                                                 setup : setupPopupParams,\r
729                                                                                 commit : commitPopupParams\r
730 \r
731                                                                         },\r
732                                                                         {\r
733                                                                                 type : 'checkbox',\r
734                                                                                 id : 'fullscreen',\r
735                                                                                 label : editor.lang.link.popupFullScreen,\r
736                                                                                 setup : setupPopupParams,\r
737                                                                                 commit : commitPopupParams\r
738 \r
739                                                                         }\r
740                                                                 ]\r
741                                                         },\r
742                                                         {\r
743                                                                 type : 'hbox',\r
744                                                                 children :\r
745                                                                 [\r
746                                                                         {\r
747                                                                                 type : 'checkbox',\r
748                                                                                 id : 'scrollbars',\r
749                                                                                 label : editor.lang.link.popupScrollBars,\r
750                                                                                 setup : setupPopupParams,\r
751                                                                                 commit : commitPopupParams\r
752 \r
753                                                                         },\r
754                                                                         {\r
755                                                                                 type : 'checkbox',\r
756                                                                                 id : 'dependent',\r
757                                                                                 label : editor.lang.link.popupDependent,\r
758                                                                                 setup : setupPopupParams,\r
759                                                                                 commit : commitPopupParams\r
760 \r
761                                                                         }\r
762                                                                 ]\r
763                                                         },\r
764                                                         {\r
765                                                                 type : 'hbox',\r
766                                                                 children :\r
767                                                                 [\r
768                                                                         {\r
769                                                                                 type :  'text',\r
770                                                                                 widths : [ '30%', '70%' ],\r
771                                                                                 labelLayout : 'horizontal',\r
772                                                                                 label : editor.lang.link.popupWidth,\r
773                                                                                 id : 'width',\r
774                                                                                 setup : setupPopupParams,\r
775                                                                                 commit : commitPopupParams\r
776 \r
777                                                                         },\r
778                                                                         {\r
779                                                                                 type :  'text',\r
780                                                                                 labelLayout : 'horizontal',\r
781                                                                                 widths : [ '55%', '45%' ],\r
782                                                                                 label : editor.lang.link.popupLeft,\r
783                                                                                 id : 'left',\r
784                                                                                 setup : setupPopupParams,\r
785                                                                                 commit : commitPopupParams\r
786 \r
787                                                                         }\r
788                                                                 ]\r
789                                                         },\r
790                                                         {\r
791                                                                 type : 'hbox',\r
792                                                                 children :\r
793                                                                 [\r
794                                                                         {\r
795                                                                                 type :  'text',\r
796                                                                                 labelLayout : 'horizontal',\r
797                                                                                 widths : [ '30%', '70%' ],\r
798                                                                                 label : editor.lang.link.popupHeight,\r
799                                                                                 id : 'height',\r
800                                                                                 setup : setupPopupParams,\r
801                                                                                 commit : commitPopupParams\r
802 \r
803                                                                         },\r
804                                                                         {\r
805                                                                                 type :  'text',\r
806                                                                                 labelLayout : 'horizontal',\r
807                                                                                 label : editor.lang.link.popupTop,\r
808                                                                                 widths : [ '55%', '45%' ],\r
809                                                                                 id : 'top',\r
810                                                                                 setup : setupPopupParams,\r
811                                                                                 commit : commitPopupParams\r
812 \r
813                                                                         }\r
814                                                                 ]\r
815                                                         }\r
816                                                 ]\r
817                                         }\r
818                                 ]\r
819                         },\r
820                         {\r
821                                 id : 'upload',\r
822                                 label : editor.lang.link.upload,\r
823                                 title : editor.lang.link.upload,\r
824                                 hidden : true,\r
825                                 filebrowser : 'uploadButton',\r
826                                 elements :\r
827                                 [\r
828                                         {\r
829                                                 type : 'file',\r
830                                                 id : 'upload',\r
831                                                 label : editor.lang.common.upload,\r
832                                                 style: 'height:40px',\r
833                                                 size : 29\r
834                                         },\r
835                                         {\r
836                                                 type : 'fileButton',\r
837                                                 id : 'uploadButton',\r
838                                                 label : editor.lang.common.uploadSubmit,\r
839                                                 filebrowser : 'info:url',\r
840                                                 'for' : [ 'upload', 'upload' ]\r
841                                         }\r
842                                 ]\r
843                         },\r
844                         {\r
845                                 id : 'advanced',\r
846                                 label : editor.lang.link.advanced,\r
847                                 title : editor.lang.link.advanced,\r
848                                 elements :\r
849                                 [\r
850                                         {\r
851                                                 type : 'vbox',\r
852                                                 padding : 1,\r
853                                                 children :\r
854                                                 [\r
855                                                         {\r
856                                                                 type : 'hbox',\r
857                                                                 widths : [ '45%', '35%', '20%' ],\r
858                                                                 children :\r
859                                                                 [\r
860                                                                         {\r
861                                                                                 type : 'text',\r
862                                                                                 id : 'advId',\r
863                                                                                 label : editor.lang.link.id,\r
864                                                                                 setup : setupAdvParams,\r
865                                                                                 commit : commitAdvParams\r
866                                                                         },\r
867                                                                         {\r
868                                                                                 type : 'select',\r
869                                                                                 id : 'advLangDir',\r
870                                                                                 label : editor.lang.link.langDir,\r
871                                                                                 'default' : '',\r
872                                                                                 style : 'width:110px',\r
873                                                                                 items :\r
874                                                                                 [\r
875                                                                                         [ editor.lang.link.langDirNotSet, '' ],\r
876                                                                                         [ editor.lang.link.langDirLTR, 'ltr' ],\r
877                                                                                         [ editor.lang.link.langDirRTL, 'rtl' ]\r
878                                                                                 ],\r
879                                                                                 setup : setupAdvParams,\r
880                                                                                 commit : commitAdvParams\r
881                                                                         },\r
882                                                                         {\r
883                                                                                 type : 'text',\r
884                                                                                 id : 'advAccessKey',\r
885                                                                                 width : '80px',\r
886                                                                                 label : editor.lang.link.acccessKey,\r
887                                                                                 maxLength : 1,\r
888                                                                                 setup : setupAdvParams,\r
889                                                                                 commit : commitAdvParams\r
890 \r
891                                                                         }\r
892                                                                 ]\r
893                                                         },\r
894                                                         {\r
895                                                                 type : 'hbox',\r
896                                                                 widths : [ '45%', '35%', '20%' ],\r
897                                                                 children :\r
898                                                                 [\r
899                                                                         {\r
900                                                                                 type : 'text',\r
901                                                                                 label : editor.lang.link.name,\r
902                                                                                 id : 'advName',\r
903                                                                                 setup : setupAdvParams,\r
904                                                                                 commit : commitAdvParams\r
905 \r
906                                                                         },\r
907                                                                         {\r
908                                                                                 type : 'text',\r
909                                                                                 label : editor.lang.link.langCode,\r
910                                                                                 id : 'advLangCode',\r
911                                                                                 width : '110px',\r
912                                                                                 'default' : '',\r
913                                                                                 setup : setupAdvParams,\r
914                                                                                 commit : commitAdvParams\r
915 \r
916                                                                         },\r
917                                                                         {\r
918                                                                                 type : 'text',\r
919                                                                                 label : editor.lang.link.tabIndex,\r
920                                                                                 id : 'advTabIndex',\r
921                                                                                 width : '80px',\r
922                                                                                 maxLength : 5,\r
923                                                                                 setup : setupAdvParams,\r
924                                                                                 commit : commitAdvParams\r
925 \r
926                                                                         }\r
927                                                                 ]\r
928                                                         }\r
929                                                 ]\r
930                                         },\r
931                                         {\r
932                                                 type : 'vbox',\r
933                                                 padding : 1,\r
934                                                 children :\r
935                                                 [\r
936                                                         {\r
937                                                                 type : 'hbox',\r
938                                                                 widths : [ '45%', '55%' ],\r
939                                                                 children :\r
940                                                                 [\r
941                                                                         {\r
942                                                                                 type : 'text',\r
943                                                                                 label : editor.lang.link.advisoryTitle,\r
944                                                                                 'default' : '',\r
945                                                                                 id : 'advTitle',\r
946                                                                                 setup : setupAdvParams,\r
947                                                                                 commit : commitAdvParams\r
948 \r
949                                                                         },\r
950                                                                         {\r
951                                                                                 type : 'text',\r
952                                                                                 label : editor.lang.link.advisoryContentType,\r
953                                                                                 'default' : '',\r
954                                                                                 id : 'advContentType',\r
955                                                                                 setup : setupAdvParams,\r
956                                                                                 commit : commitAdvParams\r
957 \r
958                                                                         }\r
959                                                                 ]\r
960                                                         },\r
961                                                         {\r
962                                                                 type : 'hbox',\r
963                                                                 widths : [ '45%', '55%' ],\r
964                                                                 children :\r
965                                                                 [\r
966                                                                         {\r
967                                                                                 type : 'text',\r
968                                                                                 label : editor.lang.link.cssClasses,\r
969                                                                                 'default' : '',\r
970                                                                                 id : 'advCSSClasses',\r
971                                                                                 setup : setupAdvParams,\r
972                                                                                 commit : commitAdvParams\r
973 \r
974                                                                         },\r
975                                                                         {\r
976                                                                                 type : 'text',\r
977                                                                                 label : editor.lang.link.charset,\r
978                                                                                 'default' : '',\r
979                                                                                 id : 'advCharset',\r
980                                                                                 setup : setupAdvParams,\r
981                                                                                 commit : commitAdvParams\r
982 \r
983                                                                         }\r
984                                                                 ]\r
985                                                         },\r
986                                                         {\r
987                                                                 type : 'hbox',\r
988                                                                 children :\r
989                                                                 [\r
990                                                                         {\r
991                                                                                 type : 'text',\r
992                                                                                 label : editor.lang.link.styles,\r
993                                                                                 'default' : '',\r
994                                                                                 id : 'advStyles',\r
995                                                                                 setup : setupAdvParams,\r
996                                                                                 commit : commitAdvParams\r
997 \r
998                                                                         }\r
999                                                                 ]\r
1000                                                         }\r
1001                                                 ]\r
1002                                         }\r
1003                                 ]\r
1004                         }\r
1005                 ],\r
1006                 onShow : function()\r
1007                 {\r
1008                         this.fakeObj = false;\r
1009 \r
1010                         var editor = this.getParentEditor(),\r
1011                                 selection = editor.getSelection(),\r
1012                                 ranges = selection.getRanges(),\r
1013                                 element = null,\r
1014                                 me = this;\r
1015                         // Fill in all the relevant fields if there's already one link selected.\r
1016                         if ( ranges.length == 1 )\r
1017                         {\r
1018 \r
1019                                 var rangeRoot = ranges[0].getCommonAncestor( true );\r
1020                                 element = rangeRoot.getAscendant( 'a', true );\r
1021                                 if ( element && element.getAttribute( 'href' ) )\r
1022                                 {\r
1023                                         selection.selectElement( element );\r
1024                                 }\r
1025                                 else if ( ( element = rangeRoot.getAscendant( 'img', true ) ) &&\r
1026                                                  element.getAttribute( '_cke_real_element_type' ) &&\r
1027                                                  element.getAttribute( '_cke_real_element_type' ) == 'anchor' )\r
1028                                 {\r
1029                                         this.fakeObj = element;\r
1030                                         element = editor.restoreRealElement( this.fakeObj );\r
1031                                         selection.selectElement( this.fakeObj );\r
1032                                 }\r
1033                                 else\r
1034                                         element = null;\r
1035                         }\r
1036 \r
1037                         this.setupContent( parseLink.apply( this, [ editor, element ] ) );\r
1038                 },\r
1039                 onOk : function()\r
1040                 {\r
1041                         var attributes = { href : 'javascript:void(0)/*' + CKEDITOR.tools.getNextNumber() + '*/' },\r
1042                                 removeAttributes = [],\r
1043                                 data = { href : attributes.href },\r
1044                                 me = this, editor = this.getParentEditor();\r
1045 \r
1046                         this.commitContent( data );\r
1047 \r
1048                         // Compose the URL.\r
1049                         switch ( data.type || 'url' )\r
1050                         {\r
1051                                 case 'url':\r
1052                                         var protocol = ( data.url && data.url.protocol != undefined ) ? data.url.protocol : 'http://',\r
1053                                                 url = ( data.url && data.url.url ) || '';\r
1054                                         attributes._cke_saved_href = ( url.indexOf( '/' ) === 0 ) ? url : protocol + url;\r
1055                                         break;\r
1056                                 case 'anchor':\r
1057                                         var name = ( data.anchor && data.anchor.name ),\r
1058                                                 id = ( data.anchor && data.anchor.id );\r
1059                                         attributes._cke_saved_href = '#' + ( name || id || '' );\r
1060                                         break;\r
1061                                 case 'email':\r
1062                                         var address = ( data.email && data.email.address ),\r
1063                                                 subject = ( data.email && encodeURIComponent( data.email.subject || '' ) ),\r
1064                                                 body = ( data.email && encodeURIComponent( data.email.body || '' ) ),\r
1065                                                 linkList = [ 'mailto:', address ];\r
1066                                         if ( subject || body )\r
1067                                         {\r
1068                                                 var argList = [];\r
1069                                                 linkList.push( '?' );\r
1070                                                 subject && argList.push( 'subject=' + subject );\r
1071                                                 body && argList.push( 'body=' + body );\r
1072                                                 linkList.push( argList.join( '&' ) );\r
1073                                         }\r
1074                                         attributes._cke_saved_href = linkList.join( '' );\r
1075                                         break;\r
1076                                 default:\r
1077                         }\r
1078 \r
1079                         // Popups and target.\r
1080                         if ( data.target )\r
1081                         {\r
1082                                 if ( data.target.type == 'popup' )\r
1083                                 {\r
1084                                         var onclickList = [ 'window.open(this.href, \'',\r
1085                                                         data.target.name || '', '\', \'' ];\r
1086                                         var featureList = [ 'resizable', 'status', 'location', 'toolbar', 'menubar', 'fullscreen',\r
1087                                                         'scrollbars', 'dependent' ];\r
1088                                         var featureLength = featureList.length;\r
1089                                         var addFeature = function( featureName )\r
1090                                         {\r
1091                                                 if ( data.target[ featureName ] )\r
1092                                                         featureList.push( featureName + '=' + data.target[ featureName ] );\r
1093                                         };\r
1094 \r
1095                                         for ( var i = 0 ; i < featureLength ; i++ )\r
1096                                                 featureList[i] = featureList[i] + ( data.target[ featureList[i] ] ? '=yes' : '=no' ) ;\r
1097                                         addFeature( 'width' );\r
1098                                         addFeature( 'left' );\r
1099                                         addFeature( 'height' );\r
1100                                         addFeature( 'top' );\r
1101 \r
1102                                         onclickList.push( featureList.join( ',' ), '\'); return false;' );\r
1103                                         attributes[ CKEDITOR.env.ie || CKEDITOR.env.webkit ? '_cke_pa_onclick' : 'onclick' ] = onclickList.join( '' );\r
1104                                 }\r
1105                                 else\r
1106                                 {\r
1107                                         if ( data.target.type != 'notSet' && data.target.name )\r
1108                                                 attributes.target = data.target.name;\r
1109                                         else\r
1110                                                 removeAttributes.push( 'target' );\r
1111 \r
1112                                         removeAttributes.push( '_cke_pa_onclick', 'onclick' );\r
1113                                 }\r
1114                         }\r
1115 \r
1116                         // Advanced attributes.\r
1117                         if ( data.adv )\r
1118                         {\r
1119                                 var advAttr = function( inputName, attrName )\r
1120                                 {\r
1121                                         var value = data.adv[ inputName ];\r
1122                                         if ( value )\r
1123                                                 attributes[attrName] = value;\r
1124                                         else\r
1125                                                 removeAttributes.push( attrName );\r
1126                                 };\r
1127 \r
1128                                 if ( this._.selectedElement )\r
1129                                         advAttr( 'advId', 'id' );\r
1130                                 advAttr( 'advLangDir', 'dir' );\r
1131                                 advAttr( 'advAccessKey', 'accessKey' );\r
1132                                 advAttr( 'advName', 'name' );\r
1133                                 advAttr( 'advLangCode', 'lang' );\r
1134                                 advAttr( 'advTabIndex', 'tabindex' );\r
1135                                 advAttr( 'advTitle', 'title' );\r
1136                                 advAttr( 'advContentType', 'type' );\r
1137                                 advAttr( 'advCSSClasses', 'class' );\r
1138                                 advAttr( 'advCharset', 'charset' );\r
1139                                 advAttr( 'advStyles', 'style' );\r
1140                         }\r
1141 \r
1142                         if ( !this._.selectedElement )\r
1143                         {\r
1144                                 // Create element if current selection is collapsed.\r
1145                                 var selection = editor.getSelection(),\r
1146                                         ranges = selection.getRanges();\r
1147                                 if ( ranges.length == 1 && ranges[0].collapsed )\r
1148                                 {\r
1149                                         var text = new CKEDITOR.dom.text( attributes._cke_saved_href, editor.document );\r
1150                                         ranges[0].insertNode( text );\r
1151                                         ranges[0].selectNodeContents( text );\r
1152                                         selection.selectRanges( ranges );\r
1153                                 }\r
1154 \r
1155                                 // Apply style.\r
1156                                 var style = new CKEDITOR.style( { element : 'a', attributes : attributes } );\r
1157                                 style.type = CKEDITOR.STYLE_INLINE;             // need to override... dunno why.\r
1158                                 style.apply( editor.document );\r
1159 \r
1160                                 // Id. Apply only to the first link.\r
1161                                 if ( data.adv && data.adv.advId )\r
1162                                 {\r
1163                                         var links = this.getParentEditor().document.$.getElementsByTagName( 'a' );\r
1164                                         for ( i = 0 ; i < links.length ; i++ )\r
1165                                         {\r
1166                                                 if ( links[i].href == attributes.href )\r
1167                                                 {\r
1168                                                         links[i].id = data.adv.advId;\r
1169                                                         break;\r
1170                                                 }\r
1171                                         }\r
1172                                 }\r
1173                         }\r
1174                         else\r
1175                         {\r
1176                                 // We're only editing an existing link, so just overwrite the attributes.\r
1177                                 var element = this._.selectedElement;\r
1178 \r
1179                                 // IE BUG: Setting the name attribute to an existing link doesn't work.\r
1180                                 // Must re-create the link from weired syntax to workaround.\r
1181                                 if ( CKEDITOR.env.ie && attributes.name != element.getAttribute( 'name' ) )\r
1182                                 {\r
1183                                         var newElement = new CKEDITOR.dom.element( '<a name="' + CKEDITOR.tools.htmlEncode( attributes.name ) + '">',\r
1184                                                         editor.document );\r
1185 \r
1186                                         selection = editor.getSelection();\r
1187 \r
1188                                         element.moveChildren( newElement );\r
1189                                         element.copyAttributes( newElement, { name : 1 } );\r
1190                                         newElement.replace( element );\r
1191                                         element = newElement;\r
1192 \r
1193                                         selection.selectElement( element );\r
1194                                 }\r
1195 \r
1196                                 element.setAttributes( attributes );\r
1197                                 element.removeAttributes( removeAttributes );\r
1198 \r
1199                                 // Make the element display as an anchor if a name has been set.\r
1200                                 if ( element.getAttribute( 'name' ) )\r
1201                                         element.addClass( 'cke_anchor' );\r
1202                                 else\r
1203                                         element.removeClass( 'cke_anchor' );\r
1204 \r
1205                                 if ( this.fakeObj )\r
1206                                         editor.createFakeElement( element, 'cke_anchor', 'anchor' ).replace( this.fakeObj );\r
1207 \r
1208                                 delete this._.selectedElement;\r
1209                         }\r
1210                 },\r
1211                 onLoad : function()\r
1212                 {\r
1213                         if ( !editor.config.linkShowAdvancedTab )\r
1214                                 this.hidePage( 'advanced' );            //Hide Advanded tab.\r
1215 \r
1216                         if ( !editor.config.linkShowTargetTab )\r
1217                                 this.hidePage( 'target' );              //Hide Target tab.\r
1218 \r
1219                 }\r
1220         };\r
1221 } );\r