Ticket #2220: fck_link.2.patch

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