Ticket #4340: 4340_3.patch

File 4340_3.patch, 9.9 KB (added by Garry Yao, 13 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 ( href && ( urlMatch = href.match( urlRegex ) ) )            // urlRegex matches empty strings, so need to check for href as well.
    9294                {
    93                         emailMatch = href.match( emailRegex );
    94                         anchorMatch = href.match( anchorRegex );
    95                         urlMatch = href.match( urlRegex );
     95                        retval.type = 'url';
     96                        retval.url = {};
     97                        retval.url.protocol = urlMatch[1];
     98                        retval.url.url = urlMatch[2];
    9699                }
     100                else if ( anchorMatch = href.match( anchorRegex ) )
     101                {
     102                        retval.type = 'anchor';
     103                        retval.anchor = {};
     104                        retval.anchor.name = retval.anchor.id = anchorMatch[1];
     105                }
     106                // Protected email link as encoded string.
     107                else if ( !emailProtection || emailProtection == 'encode' )
     108                {
     109                        if( emailProtection == 'encode' )
     110                        {
     111                                href = href.replace( encodedEmailLinkRegex,
     112                                                function ( match, protectedAddress, rest )
     113                                                {
     114                                                        return 'mailto:' +
     115                                                               String.fromCharCode.apply( String, protectedAddress.split( ',' ) ) +
     116                                                               ( rest && unescapeSingleQuote( rest ) );
     117                                                } );
     118                        }
    97119
    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];
     120                        emailMatch = href.match( emailRegex );
     121
     122                        if( emailMatch )
     123                        {
     124                                var subjectMatch = href.match( emailSubjectRegex ),
     125                                        bodyMatch = href.match( emailBodyRegex );
     126
     127                                retval.type = 'email';
     128                                var email = ( retval.email = {} );
     129                                email.address = emailMatch[ 1 ];
     130                                subjectMatch && ( email.subject = decodeURIComponent( subjectMatch[ 1 ] ) );
     131                                bodyMatch && ( email.body = decodeURIComponent( bodyMatch[ 1 ] ) );
     132                        }
    114133                }
    115                 else if ( href && urlMatch )            // urlRegex matches empty strings, so need to check for href as well.
     134                // Protected email link as function call.
     135                else if( emailProtection )
    116136                {
    117                         retval.type = 'url';
    118                         retval.url = {};
    119                         retval.url.protocol = urlMatch[1];
    120                         retval.url.url = urlMatch[2];
    121                 }
     137                        href.replace( functionCallProtectedEmailLinkRegex, function( match, funcName, funcArgs )
     138                        {
     139                                if( funcName == compiledProtectionFunction.name )
     140                                {
     141                                        retval.type = 'email';
     142                                        var email = retval.email = {};
     143
     144                                        var paramRegex = /[^,\s]+/g,
     145                                                paramQuoteRegex = /(^')|('$)/g,
     146                                                paramsMatch = funcArgs.match( paramRegex ),
     147                                                paramsMatchLength = paramsMatch.length,
     148                                                paramName,
     149                                                paramVal;
     150
     151                                        for ( var i = 0; i < paramsMatchLength; i++ )
     152                                        {
     153                                                paramVal = decodeURIComponent( unescapeSingleQuote( paramsMatch[ i ].replace( paramQuoteRegex, '' ) ) );
     154                                                paramName = compiledProtectionFunction.params[ i ].toLowerCase();
     155                                                email[ paramName ] = paramVal;
     156                                        }
     157                                        email.address = [ email.name, email.domain ].join( '@' );
     158                                }
     159                        } );
     160                }
    122161                else
    123162                        retval.type = 'url';
    124163
     
    245284                return commitParams.call( this, 'adv', data );
    246285        };
    247286
     287        function unescapeSingleQuote( str )
     288        {
     289                return str.replace( /\\'/g, '\'' );
     290        }
     291
     292        function escapeSingleQuote( str )
     293        {
     294                return str.replace( /'/g, '\\$&' );
     295        }
     296
     297        var emailProtection = editor.config.emailProtection || '';
     298
     299        // Compile the protection function pattern.
     300        if( emailProtection && emailProtection != 'encode' )
     301        {
     302                var compiledProtectionFunction = {};
     303
     304                emailProtection.replace( /^([^(]+)\(([^)]+)\)$/, function( match, funcName, params )
     305                {
     306                        compiledProtectionFunction.name = funcName;
     307                        compiledProtectionFunction.params = [];
     308                        params.replace( /[^,\s]+/g, function( param )
     309                        {
     310                                compiledProtectionFunction.params.push( param );
     311                        } );
     312                } );
     313        }
     314
     315        function protectEmailLinkAsFunction( email )
     316        {
     317                var retval,
     318                        name = compiledProtectionFunction.name,
     319                        params = compiledProtectionFunction.params,
     320                        paramName,
     321                        paramValue;
     322
     323                retval = [ name, '(' ];
     324                for ( var i = 0; i < params.length; i++ )
     325                {
     326                        paramName = params[ i ].toLowerCase();
     327                        paramValue = email[ paramName ];
     328
     329                        i > 0 && retval.push( ',' );
     330                        retval.push( '\'',
     331                                                 paramValue ?
     332                                                 escapeSingleQuote( encodeURIComponent( email[ paramName ] ) )
     333                                                 : '',
     334                                                 '\'');
     335                }
     336                retval.push( ')' );
     337                return retval.join( '' );
     338        }
     339
     340        function protectEmailAddressAsEncodedString( address )
     341        {
     342                var charCode,
     343                        length = address.length,
     344                        encodedChars = [];
     345                for ( var i = 0; i < length; i++ )
     346                {
     347                        charCode = address.charCodeAt( i );
     348                        encodedChars.push( charCode );
     349                }
     350                return 'String.fromCharCode(' + encodedChars.join( ',' ) + ')';
     351        }
     352       
    248353        return {
    249354                title : editor.lang.link.title,
    250355                minWidth : 350,
     
    10411146                        var attributes = { href : 'javascript:void(0)/*' + CKEDITOR.tools.getNextNumber() + '*/' },
    10421147                                removeAttributes = [],
    10431148                                data = { href : attributes.href },
    1044                                 me = this, editor = this.getParentEditor();
     1149                                me = this,
     1150                                editor = this.getParentEditor();
    10451151
    10461152                        this.commitContent( data );
    10471153
     
    10591165                                        attributes._cke_saved_href = '#' + ( name || id || '' );
    10601166                                        break;
    10611167                                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 )
     1168
     1169                                        var linkHref,
     1170                                                email = data.email,
     1171                                                address = email.address;
     1172
     1173                                        switch( emailProtection )
    10671174                                        {
    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                         }
     1175                                                case '' :
     1176                                                case 'encode' :
     1177                                                {
     1178                                                        var subject = encodeURIComponent( email.subject || '' ),
     1179                                                                body = encodeURIComponent( email.body || '' );
     1180
     1181                                                        // Build the e-mail parameters first.
     1182                                                        var argList = [];
     1183                                                        subject && argList.push( 'subject=' + subject );
     1184                                                        body && argList.push( 'body=' + body );
     1185                                                        argList = argList.length ? '?' + argList.join( '&' ) : '';
     1186
     1187                                                        if ( emailProtection == 'encode' )
     1188                                                        {
     1189                                                                linkHref = [ 'javascript:void(location.href=\'mailto:\'+',
     1190                                                                                         protectEmailAddressAsEncodedString( address ) ];
     1191                                                                // parameters are optional.
     1192                                                                argList && linkHref.push( '+\'', escapeSingleQuote( argList ), '\'' );
     1193
     1194                                                                linkHref.push( ')' );
     1195                                                        }
     1196                                                        else
     1197                                                                linkHref = [ 'mailto:', address, argList ];
     1198
     1199                                                        break;
     1200                                                }
     1201                                                default :
     1202                                                {
     1203                                                        // Separating name and domain.
     1204                                                        var nameAndDomain = address.split( '@', 2 );
     1205                                                        email.name = nameAndDomain[ 0 ];
     1206                                                        email.domain = nameAndDomain[ 1 ];
     1207
     1208                                                        linkHref = [ 'javascript:', protectEmailLinkAsFunction( email ) ];
     1209                                                }
     1210                                        }
    10781211
     1212                                        attributes._cke_saved_href = linkHref.join( '' );
     1213                                        break;
     1214                        }
     1215
    10791216                        // Popups and target.
    10801217                        if ( data.target )
    10811218                        {
     
    12181355
    12191356                }
    12201357        };
    1221 } );
     1358} )
     1359
     1360/**
     1361 * The e-mail address anti-spam protection option.
     1362 * @name CKEDITOR.config.emailProtection
     1363 * @type {String}
     1364 * Two forms of protection could be choosed from :
     1365 * 1. The whole address parts ( name, domain with any other query string ) are assembled into a
     1366 *   function call pattern which invoke you own provided function, with the specified arguments.
     1367 * 2. Only the e-mail address is obfuscated into unicode code point sequences, replacement are
     1368 *   done by a String.fromCharCode() call.
     1369 * Note: Both approaches require JavaScript to be enabled.
     1370 * @default ''
     1371 * @example
     1372 *  config.emailProtection = '';
     1373 *  // href="mailto:tester@ckeditor.com?subject=subject&body=body"
     1374 *  config.emailProtection = 'encode';
     1375 *  // 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>"
     1376 *  config.emailProtection = 'mt(NAME,DOMAIN,SUBJECT,BODY)';
     1377 *  // href="javascript:mt('tester','ckeditor.com','subject','body')"
     1378 */
© 2003 – 2022, CKSource sp. z o.o. sp.k. All rights reserved. | Terms of use | Privacy policy