import torrus 1.0.9
[freeside.git] / httemplate / elements / fckeditor / editor / dialog / fck_link / fck_link.js
1 /*\r
2  * FCKeditor - The text editor for Internet - http://www.fckeditor.net\r
3  * Copyright (C) 2003-2010 Frederico Caldeira Knabben\r
4  *\r
5  * == BEGIN LICENSE ==\r
6  *\r
7  * Licensed under the terms of any of the following licenses at your\r
8  * choice:\r
9  *\r
10  *  - GNU General Public License Version 2 or later (the "GPL")\r
11  *    http://www.gnu.org/licenses/gpl.html\r
12  *\r
13  *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")\r
14  *    http://www.gnu.org/licenses/lgpl.html\r
15  *\r
16  *  - Mozilla Public License Version 1.1 or later (the "MPL")\r
17  *    http://www.mozilla.org/MPL/MPL-1.1.html\r
18  *\r
19  * == END LICENSE ==\r
20  *\r
21  * Scripts related to the Link dialog window (see fck_link.html).\r
22  */\r
23 \r
24 var dialog      = window.parent ;\r
25 var oEditor = dialog.InnerDialogLoaded() ;\r
26 \r
27 var FCK                 = oEditor.FCK ;\r
28 var FCKLang             = oEditor.FCKLang ;\r
29 var FCKConfig   = oEditor.FCKConfig ;\r
30 var FCKRegexLib = oEditor.FCKRegexLib ;\r
31 var FCKTools    = oEditor.FCKTools ;\r
32 \r
33 //#### Dialog Tabs\r
34 \r
35 // Set the dialog tabs.\r
36 dialog.AddTab( 'Info', FCKLang.DlgLnkInfoTab ) ;\r
37 \r
38 if ( !FCKConfig.LinkDlgHideTarget )\r
39         dialog.AddTab( 'Target', FCKLang.DlgLnkTargetTab, true ) ;\r
40 \r
41 if ( FCKConfig.LinkUpload )\r
42         dialog.AddTab( 'Upload', FCKLang.DlgLnkUpload, true ) ;\r
43 \r
44 if ( !FCKConfig.LinkDlgHideAdvanced )\r
45         dialog.AddTab( 'Advanced', FCKLang.DlgAdvancedTag ) ;\r
46 \r
47 // Function called when a dialog tag is selected.\r
48 function OnDialogTabChange( tabCode )\r
49 {\r
50         ShowE('divInfo'         , ( tabCode == 'Info' ) ) ;\r
51         ShowE('divTarget'       , ( tabCode == 'Target' ) ) ;\r
52         ShowE('divUpload'       , ( tabCode == 'Upload' ) ) ;\r
53         ShowE('divAttribs'      , ( tabCode == 'Advanced' ) ) ;\r
54 \r
55         dialog.SetAutoSize( true ) ;\r
56 }\r
57 \r
58 //#### Regular Expressions library.\r
59 var oRegex = new Object() ;\r
60 \r
61 oRegex.UriProtocol = /^(((http|https|ftp|news):\/\/)|mailto:)/gi ;\r
62 \r
63 oRegex.UrlOnChangeProtocol = /^(http|https|ftp|news):\/\/(?=.)/gi ;\r
64 \r
65 oRegex.UrlOnChangeTestOther = /^((javascript:)|[#\/\.])/gi ;\r
66 \r
67 oRegex.ReserveTarget = /^_(blank|self|top|parent)$/i ;\r
68 \r
69 oRegex.PopupUri = /^javascript:void\(\s*window.open\(\s*'([^']+)'\s*,\s*(?:'([^']*)'|null)\s*,\s*'([^']*)'\s*\)\s*\)\s*$/ ;\r
70 \r
71 // Accessible popups\r
72 oRegex.OnClickPopup = /^\s*on[cC]lick="\s*window.open\(\s*this\.href\s*,\s*(?:'([^']*)'|null)\s*,\s*'([^']*)'\s*\)\s*;\s*return\s*false;*\s*"$/ ;\r
73 \r
74 oRegex.PopupFeatures = /(?:^|,)([^=]+)=(\d+|yes|no)/gi ;\r
75 \r
76 //#### Parser Functions\r
77 \r
78 var oParser = new Object() ;\r
79 \r
80 // This method simply returns the two inputs in numerical order. You can even\r
81 // provide strings, as the method would parseInt() the values.\r
82 oParser.SortNumerical = function(a, b)\r
83 {\r
84         return parseInt( a, 10 ) - parseInt( b, 10 ) ;\r
85 }\r
86 \r
87 oParser.ParseEMailParams = function(sParams)\r
88 {\r
89         // Initialize the oEMailParams object.\r
90         var oEMailParams = new Object() ;\r
91         oEMailParams.Subject = '' ;\r
92         oEMailParams.Body = '' ;\r
93 \r
94         var aMatch = sParams.match( /(^|^\?|&)subject=([^&]+)/i ) ;\r
95         if ( aMatch ) oEMailParams.Subject = decodeURIComponent( aMatch[2] ) ;\r
96 \r
97         aMatch = sParams.match( /(^|^\?|&)body=([^&]+)/i ) ;\r
98         if ( aMatch ) oEMailParams.Body = decodeURIComponent( aMatch[2] ) ;\r
99 \r
100         return oEMailParams ;\r
101 }\r
102 \r
103 // This method returns either an object containing the email info, or FALSE\r
104 // if the parameter is not an email link.\r
105 oParser.ParseEMailUri = function( sUrl )\r
106 {\r
107         // Initializes the EMailInfo object.\r
108         var oEMailInfo = new Object() ;\r
109         oEMailInfo.Address = '' ;\r
110         oEMailInfo.Subject = '' ;\r
111         oEMailInfo.Body = '' ;\r
112 \r
113         var aLinkInfo = sUrl.match( /^(\w+):(.*)$/ ) ;\r
114         if ( aLinkInfo && aLinkInfo[1] == 'mailto' )\r
115         {\r
116                 // This seems to be an unprotected email link.\r
117                 var aParts = aLinkInfo[2].match( /^([^\?]+)\??(.+)?/ ) ;\r
118                 if ( aParts )\r
119                 {\r
120                         // Set the e-mail address.\r
121                         oEMailInfo.Address = aParts[1] ;\r
122 \r
123                         // Look for the optional e-mail parameters.\r
124                         if ( aParts[2] )\r
125                         {\r
126                                 var oEMailParams = oParser.ParseEMailParams( aParts[2] ) ;\r
127                                 oEMailInfo.Subject = oEMailParams.Subject ;\r
128                                 oEMailInfo.Body = oEMailParams.Body ;\r
129                         }\r
130                 }\r
131                 return oEMailInfo ;\r
132         }\r
133         else if ( aLinkInfo && aLinkInfo[1] == 'javascript' )\r
134         {\r
135                 // This may be a protected email.\r
136 \r
137                 // Try to match the url against the EMailProtectionFunction.\r
138                 var func = FCKConfig.EMailProtectionFunction ;\r
139                 if ( func != null )\r
140                 {\r
141                         try\r
142                         {\r
143                                 // Escape special chars.\r
144                                 func = func.replace( /([\/^$*+.?()\[\]])/g, '\\$1' ) ;\r
145 \r
146                                 // Define the possible keys.\r
147                                 var keys = new Array('NAME', 'DOMAIN', 'SUBJECT', 'BODY') ;\r
148 \r
149                                 // Get the order of the keys (hold them in the array <pos>) and\r
150                                 // the function replaced by regular expression patterns.\r
151                                 var sFunc = func ;\r
152                                 var pos = new Array() ;\r
153                                 for ( var i = 0 ; i < keys.length ; i ++ )\r
154                                 {\r
155                                         var rexp = new RegExp( keys[i] ) ;\r
156                                         var p = func.search( rexp ) ;\r
157                                         if ( p >= 0 )\r
158                                         {\r
159                                                 sFunc = sFunc.replace( rexp, '\'([^\']*)\'' ) ;\r
160                                                 pos[pos.length] = p + ':' + keys[i] ;\r
161                                         }\r
162                                 }\r
163 \r
164                                 // Sort the available keys.\r
165                                 pos.sort( oParser.SortNumerical ) ;\r
166 \r
167                                 // Replace the excaped single quotes in the url, such they do\r
168                                 // not affect the regexp afterwards.\r
169                                 aLinkInfo[2] = aLinkInfo[2].replace( /\\'/g, '###SINGLE_QUOTE###' ) ;\r
170 \r
171                                 // Create the regexp and execute it.\r
172                                 var rFunc = new RegExp( '^' + sFunc + '$' ) ;\r
173                                 var aMatch = rFunc.exec( aLinkInfo[2] ) ;\r
174                                 if ( aMatch )\r
175                                 {\r
176                                         var aInfo = new Array();\r
177                                         for ( var i = 1 ; i < aMatch.length ; i ++ )\r
178                                         {\r
179                                                 var k = pos[i-1].match(/^\d+:(.+)$/) ;\r
180                                                 aInfo[k[1]] = aMatch[i].replace(/###SINGLE_QUOTE###/g, '\'') ;\r
181                                         }\r
182 \r
183                                         // Fill the EMailInfo object that will be returned\r
184                                         oEMailInfo.Address = aInfo['NAME'] + '@' + aInfo['DOMAIN'] ;\r
185                                         oEMailInfo.Subject = decodeURIComponent( aInfo['SUBJECT'] ) ;\r
186                                         oEMailInfo.Body = decodeURIComponent( aInfo['BODY'] ) ;\r
187 \r
188                                         return oEMailInfo ;\r
189                                 }\r
190                         }\r
191                         catch (e)\r
192                         {\r
193                         }\r
194                 }\r
195 \r
196                 // Try to match the email against the encode protection.\r
197                 var aMatch = aLinkInfo[2].match( /^(?:void\()?location\.href='mailto:'\+(String\.fromCharCode\([\d,]+\))\+'(.*)'\)?$/ ) ;\r
198                 if ( aMatch )\r
199                 {\r
200                         // The link is encoded\r
201                         oEMailInfo.Address = eval( aMatch[1] ) ;\r
202                         if ( aMatch[2] )\r
203                         {\r
204                                 var oEMailParams = oParser.ParseEMailParams( aMatch[2] ) ;\r
205                                 oEMailInfo.Subject = oEMailParams.Subject ;\r
206                                 oEMailInfo.Body = oEMailParams.Body ;\r
207                         }\r
208                         return oEMailInfo ;\r
209                 }\r
210         }\r
211         return false;\r
212 }\r
213 \r
214 oParser.CreateEMailUri = function( address, subject, body )\r
215 {\r
216         // Switch for the EMailProtection setting.\r
217         switch ( FCKConfig.EMailProtection )\r
218         {\r
219                 case 'function' :\r
220                         var func = FCKConfig.EMailProtectionFunction ;\r
221                         if ( func == null )\r
222                         {\r
223                                 if ( FCKConfig.Debug )\r
224                                 {\r
225                                         alert('EMailProtection alert!\nNo function defined. Please set "FCKConfig.EMailProtectionFunction"') ;\r
226                                 }\r
227                                 return '';\r
228                         }\r
229 \r
230                         // Split the email address into name and domain parts.\r
231                         var aAddressParts = address.split( '@', 2 ) ;\r
232                         if ( aAddressParts[1] == undefined )\r
233                         {\r
234                                 aAddressParts[1] = '' ;\r
235                         }\r
236 \r
237                         // Replace the keys by their values (embedded in single quotes).\r
238                         func = func.replace(/NAME/g, "'" + aAddressParts[0].replace(/'/g, '\\\'') + "'") ;\r
239                         func = func.replace(/DOMAIN/g, "'" + aAddressParts[1].replace(/'/g, '\\\'') + "'") ;\r
240                         func = func.replace(/SUBJECT/g, "'" + encodeURIComponent( subject ).replace(/'/g, '\\\'') + "'") ;\r
241                         func = func.replace(/BODY/g, "'" + encodeURIComponent( body ).replace(/'/g, '\\\'') + "'") ;\r
242 \r
243                         return 'javascript:' + func ;\r
244 \r
245                 case 'encode' :\r
246                         var aParams = [] ;\r
247                         var aAddressCode = [] ;\r
248 \r
249                         if ( subject.length > 0 )\r
250                                 aParams.push( 'subject='+ encodeURIComponent( subject ) ) ;\r
251                         if ( body.length > 0 )\r
252                                 aParams.push( 'body=' + encodeURIComponent( body ) ) ;\r
253                         for ( var i = 0 ; i < address.length ; i++ )\r
254                                 aAddressCode.push( address.charCodeAt( i ) ) ;\r
255 \r
256                         return 'javascript:void(location.href=\'mailto:\'+String.fromCharCode(' + aAddressCode.join( ',' ) + ')+\'?' + aParams.join( '&' ) + '\')' ;\r
257         }\r
258 \r
259         // EMailProtection 'none'\r
260 \r
261         var sBaseUri = 'mailto:' + address ;\r
262 \r
263         var sParams = '' ;\r
264 \r
265         if ( subject.length > 0 )\r
266                 sParams = '?subject=' + encodeURIComponent( subject ) ;\r
267 \r
268         if ( body.length > 0 )\r
269         {\r
270                 sParams += ( sParams.length == 0 ? '?' : '&' ) ;\r
271                 sParams += 'body=' + encodeURIComponent( body ) ;\r
272         }\r
273 \r
274         return sBaseUri + sParams ;\r
275 }\r
276 \r
277 //#### Initialization Code\r
278 \r
279 // oLink: The actual selected link in the editor.\r
280 var oLink = dialog.Selection.GetSelection().MoveToAncestorNode( 'A' ) ;\r
281 if ( oLink )\r
282         FCK.Selection.SelectNode( oLink ) ;\r
283 \r
284 window.onload = function()\r
285 {\r
286         // Translate the dialog box texts.\r
287         oEditor.FCKLanguageManager.TranslatePage(document) ;\r
288 \r
289         // Fill the Anchor Names and Ids combos.\r
290         LoadAnchorNamesAndIds() ;\r
291 \r
292         // Load the selected link information (if any).\r
293         LoadSelection() ;\r
294 \r
295         // Update the dialog box.\r
296         SetLinkType( GetE('cmbLinkType').value ) ;\r
297 \r
298         // Show/Hide the "Browse Server" button.\r
299         GetE('divBrowseServer').style.display = FCKConfig.LinkBrowser ? '' : 'none' ;\r
300 \r
301         // Show the initial dialog content.\r
302         GetE('divInfo').style.display = '' ;\r
303 \r
304         // Set the actual uploader URL.\r
305         if ( FCKConfig.LinkUpload )\r
306                 GetE('frmUpload').action = FCKConfig.LinkUploadURL ;\r
307 \r
308         // Set the default target (from configuration).\r
309         SetDefaultTarget() ;\r
310 \r
311         // Activate the "OK" button.\r
312         dialog.SetOkButton( true ) ;\r
313 \r
314         // Select the first field.\r
315         switch( GetE('cmbLinkType').value )\r
316         {\r
317                 case 'url' :\r
318                         SelectField( 'txtUrl' ) ;\r
319                         break ;\r
320                 case 'email' :\r
321                         SelectField( 'txtEMailAddress' ) ;\r
322                         break ;\r
323                 case 'anchor' :\r
324                         if ( GetE('divSelAnchor').style.display != 'none' )\r
325                                 SelectField( 'cmbAnchorName' ) ;\r
326                         else\r
327                                 SelectField( 'cmbLinkType' ) ;\r
328         }\r
329 }\r
330 \r
331 var bHasAnchors ;\r
332 \r
333 function LoadAnchorNamesAndIds()\r
334 {\r
335         // Since version 2.0, the anchors are replaced in the DOM by IMGs so the user see the icon\r
336         // to edit them. So, we must look for that images now.\r
337         var aAnchors = new Array() ;\r
338         var i ;\r
339         var oImages = oEditor.FCK.EditorDocument.getElementsByTagName( 'IMG' ) ;\r
340         for( i = 0 ; i < oImages.length ; i++ )\r
341         {\r
342                 if ( oImages[i].getAttribute('_fckanchor') )\r
343                         aAnchors[ aAnchors.length ] = oEditor.FCK.GetRealElement( oImages[i] ) ;\r
344         }\r
345 \r
346         // Add also real anchors\r
347         var oLinks = oEditor.FCK.EditorDocument.getElementsByTagName( 'A' ) ;\r
348         for( i = 0 ; i < oLinks.length ; i++ )\r
349         {\r
350                 if ( oLinks[i].name && ( oLinks[i].name.length > 0 ) )\r
351                         aAnchors[ aAnchors.length ] = oLinks[i] ;\r
352         }\r
353 \r
354         var aIds = FCKTools.GetAllChildrenIds( oEditor.FCK.EditorDocument.body ) ;\r
355 \r
356         bHasAnchors = ( aAnchors.length > 0 || aIds.length > 0 ) ;\r
357 \r
358         for ( i = 0 ; i < aAnchors.length ; i++ )\r
359         {\r
360                 var sName = aAnchors[i].name ;\r
361                 if ( sName && sName.length > 0 )\r
362                         FCKTools.AddSelectOption( GetE('cmbAnchorName'), sName, sName ) ;\r
363         }\r
364 \r
365         for ( i = 0 ; i < aIds.length ; i++ )\r
366         {\r
367                 FCKTools.AddSelectOption( GetE('cmbAnchorId'), aIds[i], aIds[i] ) ;\r
368         }\r
369 \r
370         ShowE( 'divSelAnchor'   , bHasAnchors ) ;\r
371         ShowE( 'divNoAnchor'    , !bHasAnchors ) ;\r
372 }\r
373 \r
374 function LoadSelection()\r
375 {\r
376         if ( !oLink ) return ;\r
377 \r
378         var sType = 'url' ;\r
379 \r
380         // Get the actual Link href.\r
381         var sHRef = oLink.getAttribute( '_fcksavedurl' ) ;\r
382         if ( sHRef == null )\r
383                 sHRef = oLink.getAttribute( 'href' , 2 ) || '' ;\r
384 \r
385         // Look for a popup javascript link.\r
386         var oPopupMatch = oRegex.PopupUri.exec( sHRef ) ;\r
387         if( oPopupMatch )\r
388         {\r
389                 GetE('cmbTarget').value = 'popup' ;\r
390                 sHRef = oPopupMatch[1] ;\r
391                 FillPopupFields( oPopupMatch[2], oPopupMatch[3] ) ;\r
392                 SetTarget( 'popup' ) ;\r
393         }\r
394 \r
395         // Accessible popups, the popup data is in the onclick attribute\r
396         if ( !oPopupMatch )\r
397         {\r
398                 var onclick = oLink.getAttribute( 'onclick_fckprotectedatt' ) ;\r
399                 if ( onclick )\r
400                 {\r
401                         // Decode the protected string\r
402                         onclick = decodeURIComponent( onclick ) ;\r
403 \r
404                         oPopupMatch = oRegex.OnClickPopup.exec( onclick ) ;\r
405                         if( oPopupMatch )\r
406                         {\r
407                                 GetE( 'cmbTarget' ).value = 'popup' ;\r
408                                 FillPopupFields( oPopupMatch[1], oPopupMatch[2] ) ;\r
409                                 SetTarget( 'popup' ) ;\r
410                         }\r
411                 }\r
412         }\r
413 \r
414         // Search for the protocol.\r
415         var sProtocol = oRegex.UriProtocol.exec( sHRef ) ;\r
416 \r
417         // Search for a protected email link.\r
418         var oEMailInfo = oParser.ParseEMailUri( sHRef );\r
419 \r
420         if ( oEMailInfo )\r
421         {\r
422                 sType = 'email' ;\r
423 \r
424                 GetE('txtEMailAddress').value = oEMailInfo.Address ;\r
425                 GetE('txtEMailSubject').value = oEMailInfo.Subject ;\r
426                 GetE('txtEMailBody').value    = oEMailInfo.Body ;\r
427         }\r
428         else if ( sProtocol )\r
429         {\r
430                 sProtocol = sProtocol[0].toLowerCase() ;\r
431                 GetE('cmbLinkProtocol').value = sProtocol ;\r
432 \r
433                 // Remove the protocol and get the remaining URL.\r
434                 var sUrl = sHRef.replace( oRegex.UriProtocol, '' ) ;\r
435                 sType = 'url' ;\r
436                 GetE('txtUrl').value = sUrl ;\r
437         }\r
438         else if ( sHRef.substr(0,1) == '#' && sHRef.length > 1 )        // It is an anchor link.\r
439         {\r
440                 sType = 'anchor' ;\r
441                 GetE('cmbAnchorName').value = GetE('cmbAnchorId').value = sHRef.substr(1) ;\r
442         }\r
443         else                                    // It is another type of link.\r
444         {\r
445                 sType = 'url' ;\r
446 \r
447                 GetE('cmbLinkProtocol').value = '' ;\r
448                 GetE('txtUrl').value = sHRef ;\r
449         }\r
450 \r
451         if ( !oPopupMatch )\r
452         {\r
453                 // Get the target.\r
454                 var sTarget = oLink.target ;\r
455 \r
456                 if ( sTarget && sTarget.length > 0 )\r
457                 {\r
458                         if ( oRegex.ReserveTarget.test( sTarget ) )\r
459                         {\r
460                                 sTarget = sTarget.toLowerCase() ;\r
461                                 GetE('cmbTarget').value = sTarget ;\r
462                         }\r
463                         else\r
464                                 GetE('cmbTarget').value = 'frame' ;\r
465                         GetE('txtTargetFrame').value = sTarget ;\r
466                 }\r
467         }\r
468 \r
469         // Get Advances Attributes\r
470         GetE('txtAttId').value                  = oLink.id ;\r
471         GetE('txtAttName').value                = oLink.name ;\r
472         GetE('cmbAttLangDir').value             = oLink.dir ;\r
473         GetE('txtAttLangCode').value    = oLink.lang ;\r
474         GetE('txtAttAccessKey').value   = oLink.accessKey ;\r
475         GetE('txtAttTabIndex').value    = oLink.tabIndex <= 0 ? '' : oLink.tabIndex ;\r
476         GetE('txtAttTitle').value               = oLink.title ;\r
477         GetE('txtAttContentType').value = oLink.type ;\r
478         GetE('txtAttCharSet').value             = oLink.charset ;\r
479 \r
480         var sClass ;\r
481         if ( oEditor.FCKBrowserInfo.IsIE )\r
482         {\r
483                 sClass  = oLink.getAttribute('className',2) || '' ;\r
484                 // Clean up temporary classes for internal use:\r
485                 sClass = sClass.replace( FCKRegexLib.FCK_Class, '' ) ;\r
486 \r
487                 GetE('txtAttStyle').value       = oLink.style.cssText ;\r
488         }\r
489         else\r
490         {\r
491                 sClass  = oLink.getAttribute('class',2) || '' ;\r
492                 GetE('txtAttStyle').value       = oLink.getAttribute('style',2) || '' ;\r
493         }\r
494         GetE('txtAttClasses').value     = sClass ;\r
495 \r
496         // Update the Link type combo.\r
497         GetE('cmbLinkType').value = sType ;\r
498 }\r
499 \r
500 //#### Link type selection.\r
501 function SetLinkType( linkType )\r
502 {\r
503         ShowE('divLinkTypeUrl'          , (linkType == 'url') ) ;\r
504         ShowE('divLinkTypeAnchor'       , (linkType == 'anchor') ) ;\r
505         ShowE('divLinkTypeEMail'        , (linkType == 'email') ) ;\r
506 \r
507         if ( !FCKConfig.LinkDlgHideTarget )\r
508                 dialog.SetTabVisibility( 'Target'       , (linkType == 'url') ) ;\r
509 \r
510         if ( FCKConfig.LinkUpload )\r
511                 dialog.SetTabVisibility( 'Upload'       , (linkType == 'url') ) ;\r
512 \r
513         if ( !FCKConfig.LinkDlgHideAdvanced )\r
514                 dialog.SetTabVisibility( 'Advanced'     , (linkType != 'anchor' || bHasAnchors) ) ;\r
515 \r
516         if ( linkType == 'email' )\r
517                 dialog.SetAutoSize( true ) ;\r
518 }\r
519 \r
520 //#### Target type selection.\r
521 function SetTarget( targetType )\r
522 {\r
523         GetE('tdTargetFrame').style.display     = ( targetType == 'popup' ? 'none' : '' ) ;\r
524         GetE('tdPopupName').style.display       =\r
525         GetE('tablePopupFeatures').style.display = ( targetType == 'popup' ? '' : 'none' ) ;\r
526 \r
527         switch ( targetType )\r
528         {\r
529                 case "_blank" :\r
530                 case "_self" :\r
531                 case "_parent" :\r
532                 case "_top" :\r
533                         GetE('txtTargetFrame').value = targetType ;\r
534                         break ;\r
535                 case "" :\r
536                         GetE('txtTargetFrame').value = '' ;\r
537                         break ;\r
538         }\r
539 \r
540         if ( targetType == 'popup' )\r
541                 dialog.SetAutoSize( true ) ;\r
542 }\r
543 \r
544 //#### Called while the user types the URL.\r
545 function OnUrlChange()\r
546 {\r
547         var sUrl = GetE('txtUrl').value ;\r
548         var sProtocol = oRegex.UrlOnChangeProtocol.exec( sUrl ) ;\r
549 \r
550         if ( sProtocol )\r
551         {\r
552                 sUrl = sUrl.substr( sProtocol[0].length ) ;\r
553                 GetE('txtUrl').value = sUrl ;\r
554                 GetE('cmbLinkProtocol').value = sProtocol[0].toLowerCase() ;\r
555         }\r
556         else if ( oRegex.UrlOnChangeTestOther.test( sUrl ) )\r
557         {\r
558                 GetE('cmbLinkProtocol').value = '' ;\r
559         }\r
560 }\r
561 \r
562 //#### Called while the user types the target name.\r
563 function OnTargetNameChange()\r
564 {\r
565         var sFrame = GetE('txtTargetFrame').value ;\r
566 \r
567         if ( sFrame.length == 0 )\r
568                 GetE('cmbTarget').value = '' ;\r
569         else if ( oRegex.ReserveTarget.test( sFrame ) )\r
570                 GetE('cmbTarget').value = sFrame.toLowerCase() ;\r
571         else\r
572                 GetE('cmbTarget').value = 'frame' ;\r
573 }\r
574 \r
575 // Accessible popups\r
576 function BuildOnClickPopup()\r
577 {\r
578         var sWindowName = "'" + GetE('txtPopupName').value.replace(/\W/gi, "") + "'" ;\r
579 \r
580         var sFeatures = '' ;\r
581         var aChkFeatures = document.getElementsByName( 'chkFeature' ) ;\r
582         for ( var i = 0 ; i < aChkFeatures.length ; i++ )\r
583         {\r
584                 if ( i > 0 ) sFeatures += ',' ;\r
585                 sFeatures += aChkFeatures[i].value + '=' + ( aChkFeatures[i].checked ? 'yes' : 'no' ) ;\r
586         }\r
587 \r
588         if ( GetE('txtPopupWidth').value.length > 0 )   sFeatures += ',width=' + GetE('txtPopupWidth').value ;\r
589         if ( GetE('txtPopupHeight').value.length > 0 )  sFeatures += ',height=' + GetE('txtPopupHeight').value ;\r
590         if ( GetE('txtPopupLeft').value.length > 0 )    sFeatures += ',left=' + GetE('txtPopupLeft').value ;\r
591         if ( GetE('txtPopupTop').value.length > 0 )             sFeatures += ',top=' + GetE('txtPopupTop').value ;\r
592 \r
593         if ( sFeatures != '' )\r
594                 sFeatures = sFeatures + ",status" ;\r
595 \r
596         return ( "window.open(this.href," + sWindowName + ",'" + sFeatures + "'); return false" ) ;\r
597 }\r
598 \r
599 //#### Fills all Popup related fields.\r
600 function FillPopupFields( windowName, features )\r
601 {\r
602         if ( windowName )\r
603                 GetE('txtPopupName').value = windowName ;\r
604 \r
605         var oFeatures = new Object() ;\r
606         var oFeaturesMatch ;\r
607         while( ( oFeaturesMatch = oRegex.PopupFeatures.exec( features ) ) != null )\r
608         {\r
609                 var sValue = oFeaturesMatch[2] ;\r
610                 if ( sValue == ( 'yes' || '1' ) )\r
611                         oFeatures[ oFeaturesMatch[1] ] = true ;\r
612                 else if ( ! isNaN( sValue ) && sValue != 0 )\r
613                         oFeatures[ oFeaturesMatch[1] ] = sValue ;\r
614         }\r
615 \r
616         // Update all features check boxes.\r
617         var aChkFeatures = document.getElementsByName('chkFeature') ;\r
618         for ( var i = 0 ; i < aChkFeatures.length ; i++ )\r
619         {\r
620                 if ( oFeatures[ aChkFeatures[i].value ] )\r
621                         aChkFeatures[i].checked = true ;\r
622         }\r
623 \r
624         // Update position and size text boxes.\r
625         if ( oFeatures['width'] )       GetE('txtPopupWidth').value             = oFeatures['width'] ;\r
626         if ( oFeatures['height'] )      GetE('txtPopupHeight').value    = oFeatures['height'] ;\r
627         if ( oFeatures['left'] )        GetE('txtPopupLeft').value              = oFeatures['left'] ;\r
628         if ( oFeatures['top'] )         GetE('txtPopupTop').value               = oFeatures['top'] ;\r
629 }\r
630 \r
631 //#### The OK button was hit.\r
632 function Ok()\r
633 {\r
634         var sUri, sInnerHtml ;\r
635         oEditor.FCKUndo.SaveUndoStep() ;\r
636 \r
637         switch ( GetE('cmbLinkType').value )\r
638         {\r
639                 case 'url' :\r
640                         sUri = GetE('txtUrl').value ;\r
641 \r
642                         if ( sUri.length == 0 )\r
643                         {\r
644                                 alert( FCKLang.DlnLnkMsgNoUrl ) ;\r
645                                 return false ;\r
646                         }\r
647 \r
648                         sUri = GetE('cmbLinkProtocol').value + sUri ;\r
649 \r
650                         break ;\r
651 \r
652                 case 'email' :\r
653                         sUri = GetE('txtEMailAddress').value ;\r
654 \r
655                         if ( sUri.length == 0 )\r
656                         {\r
657                                 alert( FCKLang.DlnLnkMsgNoEMail ) ;\r
658                                 return false ;\r
659                         }\r
660 \r
661                         sUri = oParser.CreateEMailUri(\r
662                                 sUri,\r
663                                 GetE('txtEMailSubject').value,\r
664                                 GetE('txtEMailBody').value ) ;\r
665                         break ;\r
666 \r
667                 case 'anchor' :\r
668                         var sAnchor = GetE('cmbAnchorName').value ;\r
669                         if ( sAnchor.length == 0 ) sAnchor = GetE('cmbAnchorId').value ;\r
670 \r
671                         if ( sAnchor.length == 0 )\r
672                         {\r
673                                 alert( FCKLang.DlnLnkMsgNoAnchor ) ;\r
674                                 return false ;\r
675                         }\r
676 \r
677                         sUri = '#' + sAnchor ;\r
678                         break ;\r
679         }\r
680 \r
681         // If no link is selected, create a new one (it may result in more than one link creation - #220).\r
682         var aLinks = oLink ? [ oLink ] : oEditor.FCK.CreateLink( sUri, true ) ;\r
683 \r
684         // If no selection, no links are created, so use the uri as the link text (by dom, 2006-05-26)\r
685         var aHasSelection = ( aLinks.length > 0 ) ;\r
686         if ( !aHasSelection )\r
687         {\r
688                 sInnerHtml = sUri;\r
689 \r
690                 // Built a better text for empty links.\r
691                 switch ( GetE('cmbLinkType').value )\r
692                 {\r
693                         // anchor: use old behavior --> return true\r
694                         case 'anchor':\r
695                                 sInnerHtml = sInnerHtml.replace( /^#/, '' ) ;\r
696                                 break ;\r
697 \r
698                         // url: try to get path\r
699                         case 'url':\r
700                                 var oLinkPathRegEx = new RegExp("//?([^?\"']+)([?].*)?$") ;\r
701                                 var asLinkPath = oLinkPathRegEx.exec( sUri ) ;\r
702                                 if (asLinkPath != null)\r
703                                         sInnerHtml = asLinkPath[1];  // use matched path\r
704                                 break ;\r
705 \r
706                         // mailto: try to get email address\r
707                         case 'email':\r
708                                 sInnerHtml = GetE('txtEMailAddress').value ;\r
709                                 break ;\r
710                 }\r
711 \r
712                 // Create a new (empty) anchor.\r
713                 aLinks = [ oEditor.FCK.InsertElement( 'a' ) ] ;\r
714         }\r
715 \r
716         for ( var i = 0 ; i < aLinks.length ; i++ )\r
717         {\r
718                 oLink = aLinks[i] ;\r
719 \r
720                 if ( aHasSelection )\r
721                         sInnerHtml = oLink.innerHTML ;          // Save the innerHTML (IE changes it if it is like an URL).\r
722 \r
723                 oLink.href = sUri ;\r
724                 SetAttribute( oLink, '_fcksavedurl', sUri ) ;\r
725 \r
726                 var onclick;\r
727                 // Accessible popups\r
728                 if( GetE('cmbTarget').value == 'popup' )\r
729                 {\r
730                         onclick = BuildOnClickPopup() ;\r
731                         // Encode the attribute\r
732                         onclick = encodeURIComponent( " onclick=\"" + onclick + "\"" )  ;\r
733                         SetAttribute( oLink, 'onclick_fckprotectedatt', onclick ) ;\r
734                 }\r
735                 else\r
736                 {\r
737                         // Check if the previous onclick was for a popup:\r
738                         // In that case remove the onclick handler.\r
739                         onclick = oLink.getAttribute( 'onclick_fckprotectedatt' ) ;\r
740                         if ( onclick )\r
741                         {\r
742                                 // Decode the protected string\r
743                                 onclick = decodeURIComponent( onclick ) ;\r
744 \r
745                                 if( oRegex.OnClickPopup.test( onclick ) )\r
746                                         SetAttribute( oLink, 'onclick_fckprotectedatt', '' ) ;\r
747                         }\r
748                 }\r
749 \r
750                 oLink.innerHTML = sInnerHtml ;          // Set (or restore) the innerHTML\r
751 \r
752                 // Target\r
753                 if( GetE('cmbTarget').value != 'popup' )\r
754                         SetAttribute( oLink, 'target', GetE('txtTargetFrame').value ) ;\r
755                 else\r
756                         SetAttribute( oLink, 'target', null ) ;\r
757 \r
758                 // Let's set the "id" only for the first link to avoid duplication.\r
759                 if ( i == 0 )\r
760                         SetAttribute( oLink, 'id', GetE('txtAttId').value ) ;\r
761 \r
762                 // Advances Attributes\r
763                 SetAttribute( oLink, 'name'             , GetE('txtAttName').value ) ;\r
764                 SetAttribute( oLink, 'dir'              , GetE('cmbAttLangDir').value ) ;\r
765                 SetAttribute( oLink, 'lang'             , GetE('txtAttLangCode').value ) ;\r
766                 SetAttribute( oLink, 'accesskey', GetE('txtAttAccessKey').value ) ;\r
767                 SetAttribute( oLink, 'tabindex' , ( GetE('txtAttTabIndex').value > 0 ? GetE('txtAttTabIndex').value : null ) ) ;\r
768                 SetAttribute( oLink, 'title'    , GetE('txtAttTitle').value ) ;\r
769                 SetAttribute( oLink, 'type'             , GetE('txtAttContentType').value ) ;\r
770                 SetAttribute( oLink, 'charset'  , GetE('txtAttCharSet').value ) ;\r
771 \r
772                 if ( oEditor.FCKBrowserInfo.IsIE )\r
773                 {\r
774                         var sClass = GetE('txtAttClasses').value ;\r
775                         // If it's also an anchor add an internal class\r
776                         if ( GetE('txtAttName').value.length != 0 )\r
777                                 sClass += ' FCK__AnchorC' ;\r
778                         SetAttribute( oLink, 'className', sClass ) ;\r
779 \r
780                         oLink.style.cssText = GetE('txtAttStyle').value ;\r
781                 }\r
782                 else\r
783                 {\r
784                         SetAttribute( oLink, 'class', GetE('txtAttClasses').value ) ;\r
785                         SetAttribute( oLink, 'style', GetE('txtAttStyle').value ) ;\r
786                 }\r
787         }\r
788 \r
789         // Select the (first) link.\r
790         oEditor.FCKSelection.SelectNode( aLinks[0] );\r
791 \r
792         return true ;\r
793 }\r
794 \r
795 function BrowseServer()\r
796 {\r
797         OpenFileBrowser( FCKConfig.LinkBrowserURL, FCKConfig.LinkBrowserWindowWidth, FCKConfig.LinkBrowserWindowHeight ) ;\r
798 }\r
799 \r
800 function SetUrl( url )\r
801 {\r
802         GetE('txtUrl').value = url ;\r
803         OnUrlChange() ;\r
804         dialog.SetSelectedTab( 'Info' ) ;\r
805 }\r
806 \r
807 function OnUploadCompleted( errorNumber, fileUrl, fileName, customMsg )\r
808 {\r
809         // Remove animation\r
810         window.parent.Throbber.Hide() ;\r
811         GetE( 'divUpload' ).style.display  = '' ;\r
812 \r
813         switch ( errorNumber )\r
814         {\r
815                 case 0 :        // No errors\r
816                         alert( 'Your file has been successfully uploaded' ) ;\r
817                         break ;\r
818                 case 1 :        // Custom error\r
819                         alert( customMsg ) ;\r
820                         return ;\r
821                 case 101 :      // Custom warning\r
822                         alert( customMsg ) ;\r
823                         break ;\r
824                 case 201 :\r
825                         alert( 'A file with the same name is already available. The uploaded file has been renamed to "' + fileName + '"' ) ;\r
826                         break ;\r
827                 case 202 :\r
828                         alert( 'Invalid file type' ) ;\r
829                         return ;\r
830                 case 203 :\r
831                         alert( "Security error. You probably don't have enough permissions to upload. Please check your server." ) ;\r
832                         return ;\r
833                 case 500 :\r
834                         alert( 'The connector is disabled' ) ;\r
835                         break ;\r
836                 default :\r
837                         alert( 'Error on file upload. Error number: ' + errorNumber ) ;\r
838                         return ;\r
839         }\r
840 \r
841         SetUrl( fileUrl ) ;\r
842         GetE('frmUpload').reset() ;\r
843 }\r
844 \r
845 var oUploadAllowedExtRegex      = new RegExp( FCKConfig.LinkUploadAllowedExtensions, 'i' ) ;\r
846 var oUploadDeniedExtRegex       = new RegExp( FCKConfig.LinkUploadDeniedExtensions, 'i' ) ;\r
847 \r
848 function CheckUpload()\r
849 {\r
850         var sFile = GetE('txtUploadFile').value ;\r
851 \r
852         if ( sFile.length == 0 )\r
853         {\r
854                 alert( 'Please select a file to upload' ) ;\r
855                 return false ;\r
856         }\r
857 \r
858         if ( ( FCKConfig.LinkUploadAllowedExtensions.length > 0 && !oUploadAllowedExtRegex.test( sFile ) ) ||\r
859                 ( FCKConfig.LinkUploadDeniedExtensions.length > 0 && oUploadDeniedExtRegex.test( sFile ) ) )\r
860         {\r
861                 OnUploadCompleted( 202 ) ;\r
862                 return false ;\r
863         }\r
864 \r
865         // Show animation\r
866         window.parent.Throbber.Show( 100 ) ;\r
867         GetE( 'divUpload' ).style.display  = 'none' ;\r
868 \r
869         return true ;\r
870 }\r
871 \r
872 function SetDefaultTarget()\r
873 {\r
874         var target = FCKConfig.DefaultLinkTarget || '' ;\r
875 \r
876         if ( oLink || target.length == 0 )\r
877                 return ;\r
878 \r
879         switch ( target )\r
880         {\r
881                 case '_blank' :\r
882                 case '_self' :\r
883                 case '_parent' :\r
884                 case '_top' :\r
885                         GetE('cmbTarget').value = target ;\r
886                         break ;\r
887                 default :\r
888                         GetE('cmbTarget').value = 'frame' ;\r
889                         break ;\r
890         }\r
891 \r
892         GetE('txtTargetFrame').value = target ;\r
893 }\r