Ticket #4340: 4340_4.patch

File 4340_4.patch, 9.9 KB (added by Garry Yao, 14 years ago)
  • _source/plugins/link/dialogs/link.js

     
    7373                emailSubjectRegex = /subject=([^;?:@&=$,\/]*)/,
    7474                emailBodyRegex = /body=([^;?:@&=$,\/]*)/,
    7575                anchorRegex = /^#(.*)$/,
    76                 urlRegex = /^((?:http|https|ftp|news):\/\/)?(.*)$/,
    77                 selectableTargets = /^(_(?:self|top|parent|blank))$/;
     76                urlRegex = /^(?!javascript)((?:http|https|ftp|news):\/\/)?(.*)$/,
     77                selectableTargets = /^(_(?:self|top|parent|blank))$/,
     78                encodedEmailLinkRegex = /^javascript:void\(location\.href='mailto:'\+String\.fromCharCode\(([^)]+)\)(?:\+'(.*)')?\)$/,
     79                functionCallProtectedEmailLinkRegex = /^javascript:([^(]+)\(([^)]+)\)$/;
    7880
    7981        var popupRegex =
    8082                /\s*window.open\(\s*this\.href\s*,\s*(?:'([^']*)'|null)\s*,\s*'([^']*)'\s*\)\s*;\s*return\s*false;*\s*/;
     
    8385        var parseLink = function( editor, element )
    8486        {
    8587                var href = element ? ( element.getAttribute( '_cke_saved_href' ) || element.getAttribute( 'href' ) ) : '',
    86                         emailMatch = '',
    87                         anchorMatch = '',
    88                         urlMatch = false,
     88                        emailMatch,
     89                        anchorMatch,
     90                        urlMatch,
    8991                        retval = {};
    90 
    91                 if ( href )
     92               
     93                if ( anchorMatch = href.match( anchorRegex ) )
    9294                {
    93                         emailMatch = href.match( emailRegex );
    94                         anchorMatch = href.match( anchorRegex );
    95                         urlMatch = href.match( urlRegex );
     95                        retval.type = 'anchor';
     96                        retval.anchor = {};
     97                        retval.anchor.name = retval.anchor.id = anchorMatch[1];
    9698                }
     99                // urlRegex matches empty strings, so need to check for href as well.
     100                else if ( href && ( urlMatch = href.match( urlRegex ) ) )
     101                {
     102                        retval.type = 'url';
     103                        retval.url = {};
     104                        retval.url.protocol = urlMatch[1];
     105                        retval.url.url = urlMatch[2];
     106                }
     107                // Protected email link as encoded string.
     108                else if ( !emailProtection || emailProtection == 'encode' )
     109                {
     110                        if( emailProtection == 'encode' )
     111                        {
     112                                href = href.replace( encodedEmailLinkRegex,
     113                                                function ( match, protectedAddress, rest )
     114                                                {
     115                                                        return 'mailto:' +
     116                                                               String.fromCharCode.apply( String, protectedAddress.split( ',' ) ) +
     117                                                               ( rest && unescapeSingleQuote( rest ) );
     118                                                } );
     119                        }
    97120
    98                 // Load the link type and URL.
    99                 if ( emailMatch )
    100                 {
    101                         var subjectMatch = href.match( emailSubjectRegex ),
    102                                 bodyMatch = href.match( emailBodyRegex );
    103                         retval.type = 'email';
    104                         retval.email = {};
    105                         retval.email.address = emailMatch[1];
    106                         subjectMatch && ( retval.email.subject = decodeURIComponent( subjectMatch[1] ) );
    107                         bodyMatch && ( retval.email.body = decodeURIComponent( bodyMatch[1] ) );
    108                 }
    109                 else if ( anchorMatch )
    110                 {
    111                         retval.type = 'anchor';
    112                         retval.anchor = {};
    113                         retval.anchor.name = retval.anchor.id = anchorMatch[1];
     121                        emailMatch = href.match( emailRegex );
     122
     123                        if( emailMatch )
     124                        {
     125                                var subjectMatch = href.match( emailSubjectRegex ),
     126                                        bodyMatch = href.match( emailBodyRegex );
     127
     128                                retval.type = 'email';
     129                                var email = ( retval.email = {} );
     130                                email.address = emailMatch[ 1 ];
     131                                subjectMatch && ( email.subject = decodeURIComponent( subjectMatch[ 1 ] ) );
     132                                bodyMatch && ( email.body = decodeURIComponent( bodyMatch[ 1 ] ) );
     133                        }
    114134                }
    115                 else if ( href && urlMatch )            // urlRegex matches empty strings, so need to check for href as well.
     135                // Protected email link as function call.
     136                else if( emailProtection )
    116137                {
    117                         retval.type = 'url';
    118                         retval.url = {};
    119                         retval.url.protocol = urlMatch[1];
    120                         retval.url.url = urlMatch[2];
    121                 }
     138                        href.replace( functionCallProtectedEmailLinkRegex, function( match, funcName, funcArgs )
     139                        {
     140                                if( funcName == compiledProtectionFunction.name )
     141                                {
     142                                        retval.type = 'email';
     143                                        var email = retval.email = {};
     144
     145                                        var paramRegex = /[^,\s]+/g,
     146                                                paramQuoteRegex = /(^')|('$)/g,
     147                                                paramsMatch = funcArgs.match( paramRegex ),
     148                                                paramsMatchLength = paramsMatch.length,
     149                                                paramName,
     150                                                paramVal;
     151
     152                                        for ( var i = 0; i < paramsMatchLength; i++ )
     153                                        {
     154                                                paramVal = decodeURIComponent( unescapeSingleQuote( paramsMatch[ i ].replace( paramQuoteRegex, '' ) ) );
     155                                                paramName = compiledProtectionFunction.params[ i ].toLowerCase();
     156                                                email[ paramName ] = paramVal;
     157                                        }
     158                                        email.address = [ email.name, email.domain ].join( '@' );
     159                                }
     160                        } );
     161                }
    122162                else
    123163                        retval.type = 'url';
    124164
     
    245285                return commitParams.call( this, 'adv', data );
    246286        };
    247287
     288        function unescapeSingleQuote( str )
     289        {
     290                return str.replace( /\\'/g, '\'' );
     291        }
     292
     293        function escapeSingleQuote( str )
     294        {
     295                return str.replace( /'/g, '\\$&' );
     296        }
     297
     298        var emailProtection = editor.config.emailProtection || '';
     299
     300        // Compile the protection function pattern.
     301        if( emailProtection && emailProtection != 'encode' )
     302        {
     303                var compiledProtectionFunction = {};
     304
     305                emailProtection.replace( /^([^(]+)\(([^)]+)\)$/, function( match, funcName, params )
     306                {
     307                        compiledProtectionFunction.name = funcName;
     308                        compiledProtectionFunction.params = [];
     309                        params.replace( /[^,\s]+/g, function( param )
     310                        {
     311                                compiledProtectionFunction.params.push( param );
     312                        } );
     313                } );
     314        }
     315
     316        function protectEmailLinkAsFunction( email )
     317        {
     318                var retval,
     319                        name = compiledProtectionFunction.name,
     320                        params = compiledProtectionFunction.params,
     321                        paramName,
     322                        paramValue;
     323
     324                retval = [ name, '(' ];
     325                for ( var i = 0; i < params.length; i++ )
     326                {
     327                        paramName = params[ i ].toLowerCase();
     328                        paramValue = email[ paramName ];
     329
     330                        i > 0 && retval.push( ',' );
     331                        retval.push( '\'',
     332                                                 paramValue ?
     333                                                 escapeSingleQuote( encodeURIComponent( email[ paramName ] ) )
     334                                                 : '',
     335                                                 '\'');
     336                }
     337                retval.push( ')' );
     338                return retval.join( '' );
     339        }
     340
     341        function protectEmailAddressAsEncodedString( address )
     342        {
     343                var charCode,
     344                        length = address.length,
     345                        encodedChars = [];
     346                for ( var i = 0; i < length; i++ )
     347                {
     348                        charCode = address.charCodeAt( i );
     349                        encodedChars.push( charCode );
     350                }
     351                return 'String.fromCharCode(' + encodedChars.join( ',' ) + ')';
     352        }
     353       
    248354        return {
    249355                title : editor.lang.link.title,
    250356                minWidth : 350,
     
    10411147                        var attributes = { href : 'javascript:void(0)/*' + CKEDITOR.tools.getNextNumber() + '*/' },
    10421148                                removeAttributes = [],
    10431149                                data = { href : attributes.href },
    1044                                 me = this, editor = this.getParentEditor();
     1150                                me = this,
     1151                                editor = this.getParentEditor();
    10451152
    10461153                        this.commitContent( data );
    10471154
     
    10591166                                        attributes._cke_saved_href = '#' + ( name || id || '' );
    10601167                                        break;
    10611168                                case 'email':
    1062                                         var address = ( data.email && data.email.address ),
    1063                                                 subject = ( data.email && encodeURIComponent( data.email.subject || '' ) ),
    1064                                                 body = ( data.email && encodeURIComponent( data.email.body || '' ) ),
    1065                                                 linkList = [ 'mailto:', address ];
    1066                                         if ( subject || body )
     1169
     1170                                        var linkHref,
     1171                                                email = data.email,
     1172                                                address = email.address;
     1173
     1174                                        switch( emailProtection )
    10671175                                        {
    1068                                                 var argList = [];
    1069                                                 linkList.push( '?' );
    1070                                                 subject && argList.push( 'subject=' + subject );
    1071                                                 body && argList.push( 'body=' + body );
    1072                                                 linkList.push( argList.join( '&' ) );
    1073                                         }
    1074                                         attributes._cke_saved_href = linkList.join( '' );
    1075                                         break;
    1076                                 default:
    1077                         }
     1176                                                case '' :
     1177                                                case 'encode' :
     1178                                                {
     1179                                                        var subject = encodeURIComponent( email.subject || '' ),
     1180                                                                body = encodeURIComponent( email.body || '' );
     1181
     1182                                                        // Build the e-mail parameters first.
     1183                                                        var argList = [];
     1184                                                        subject && argList.push( 'subject=' + subject );
     1185                                                        body && argList.push( 'body=' + body );
     1186                                                        argList = argList.length ? '?' + argList.join( '&' ) : '';
     1187
     1188                                                        if ( emailProtection == 'encode' )
     1189                                                        {
     1190                                                                linkHref = [ 'javascript:void(location.href=\'mailto:\'+',
     1191                                                                                         protectEmailAddressAsEncodedString( address ) ];
     1192                                                                // parameters are optional.
     1193                                                                argList && linkHref.push( '+\'', escapeSingleQuote( argList ), '\'' );
     1194
     1195                                                                linkHref.push( ')' );
     1196                                                        }
     1197                                                        else
     1198                                                                linkHref = [ 'mailto:', address, argList ];
     1199
     1200                                                        break;
     1201                                                }
     1202                                                default :
     1203                                                {
     1204                                                        // Separating name and domain.
     1205                                                        var nameAndDomain = address.split( '@', 2 );
     1206                                                        email.name = nameAndDomain[ 0 ];
     1207                                                        email.domain = nameAndDomain[ 1 ];
     1208
     1209                                                        linkHref = [ 'javascript:', protectEmailLinkAsFunction( email ) ];
     1210                                                }
     1211                                        }
    10781212
     1213                                        attributes._cke_saved_href = linkHref.join( '' );
     1214                                        break;
     1215                        }
     1216
    10791217                        // Popups and target.
    10801218                        if ( data.target )
    10811219                        {
     
    12181356
    12191357                }
    12201358        };
    1221 } );
     1359} )
     1360
     1361/**
     1362 * The e-mail address anti-spam protection option.
     1363 * @name CKEDITOR.config.emailProtection
     1364 * @type {String}
     1365 * Two forms of protection could be choosed from :
     1366 * 1. The whole address parts ( name, domain with any other query string ) are assembled into a
     1367 *   function call pattern which invoke you own provided function, with the specified arguments.
     1368 * 2. Only the e-mail address is obfuscated into unicode code point sequences, replacement are
     1369 *   done by a String.fromCharCode() call.
     1370 * Note: Both approaches require JavaScript to be enabled.
     1371 * @default ''
     1372 * @example
     1373 *  config.emailProtection = '';
     1374 *  // href="mailto:tester@ckeditor.com?subject=subject&body=body"
     1375 *  config.emailProtection = 'encode';
     1376 *  // href="<a href=\"javascript:void(location.href=\'mailto:\'+String.fromCharCode(116,101,115,116,101,114,64,99,107,101,100,105,116,111,114,46,99,111,109)+\'?subject=subject&body=body\')\">e-mail</a>"
     1377 *  config.emailProtection = 'mt(NAME,DOMAIN,SUBJECT,BODY)';
     1378 *  // href="javascript:mt('tester','ckeditor.com','subject','body')"
     1379 */
© 2003 – 2022, CKSource sp. z o.o. sp.k. All rights reserved. | Terms of use | Privacy policy