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 | | } |
| 99 | // Protect email link as encoded string. |
| 100 | if ( !emailProtection || emailProtection == 'encode' ) |
| 101 | { |
| 102 | if( emailProtection == 'encode' ) |
| 103 | { |
| 104 | href = href.replace( encodedEmailLinkRegex, |
| 105 | function ( match, protectedAddress, rest ) |
| 106 | { |
| 107 | return 'mailto:' + |
| 108 | String.fromCharCode.apply( String, protectedAddress.split( ',' ) ) + |
| 109 | ( rest && unescapeSingleQuote( rest ) ); |
| 110 | } ); |
| 111 | } |
| 112 | |
| 113 | emailMatch = href.match( emailRegex ); |
| 114 | |
| 115 | if( emailMatch ) |
| 116 | { |
| 117 | var subjectMatch = href.match( emailSubjectRegex ), |
| 118 | bodyMatch = href.match( emailBodyRegex ); |
| 119 | |
| 120 | retval.type = 'email'; |
| 121 | var email = ( retval.email = {} ); |
| 122 | email.address = emailMatch[ 1 ]; |
| 123 | subjectMatch && ( email.subject = decodeURIComponent( subjectMatch[ 1 ] ) ); |
| 124 | bodyMatch && ( email.body = decodeURIComponent( bodyMatch[ 1 ] ) ); |
| 125 | } |
| 126 | } |
| 127 | // Protect email link as function call. |
| 128 | else if( emailProtection ) |
| 129 | { |
| 130 | href.replace( functionCallProtectedEmailLinkRegex, function( match, funcName, funcArgs ) |
| 131 | { |
| 132 | if( funcName == compiledProtectionFunction.name ) |
| 133 | { |
| 134 | retval.type = 'email'; |
| 135 | var email = retval.email = {}; |
| 136 | |
| 137 | var paramRegex = /[^,\s]+/g, |
| 138 | paramQuoteRegex = /(^')|('$)/g, |
| 139 | paramsMatch = funcArgs.match( paramRegex ), |
| 140 | paramsMatchLength = paramsMatch.length, |
| 141 | paramName, |
| 142 | paramVal; |
| 143 | |
| 144 | for ( var i = 0; i < paramsMatchLength; i++ ) |
| 145 | { |
| 146 | paramVal = decodeURIComponent( unescapeSingleQuote( paramsMatch[ i ].replace( paramQuoteRegex, '' ) ) ); |
| 147 | paramName = compiledProtectionFunction.params[ i ].toLowerCase(); |
| 148 | email[ paramName ] = paramVal; |
| 149 | } |
| 150 | email.address = [ email.name, email.domain ].join( '@' ); |
| 151 | } |
| 152 | } ); |
| 153 | } |
| 293 | function unescapeSingleQuote( str ) |
| 294 | { |
| 295 | return str.replace( /\\'/g, '\'' ); |
| 296 | } |
| 297 | |
| 298 | function escapeSingleQuote( str ) |
| 299 | { |
| 300 | return str.replace( /'/g, '\\$&' ); |
| 301 | } |
| 302 | |
| 303 | var emailProtection = editor.config.mailProtection || ''; |
| 304 | |
| 305 | // Compile the protection function pattern. |
| 306 | if( emailProtection && emailProtection != 'encode' ) |
| 307 | { |
| 308 | var compiledProtectionFunction = {}; |
| 309 | |
| 310 | emailProtection.replace( /^([^(]+)\(([^)]+)\)$/, function( match, funcName, params ) |
| 311 | { |
| 312 | compiledProtectionFunction.name = funcName; |
| 313 | compiledProtectionFunction.params = []; |
| 314 | params.replace( /[^,\s]+/g, function( param ) |
| 315 | { |
| 316 | compiledProtectionFunction.params.push( param ); |
| 317 | } ); |
| 318 | } ); |
| 319 | } |
| 320 | |
| 321 | function protectEmailLinkAsFunction( email ) |
| 322 | { |
| 323 | var retval, |
| 324 | name = compiledProtectionFunction.name, |
| 325 | params = compiledProtectionFunction.params, |
| 326 | paramName; |
| 327 | |
| 328 | retval = [ name, '(' ]; |
| 329 | for ( var i = 0; i < params.length; i++ ) |
| 330 | { |
| 331 | paramName = params[ i ].toLowerCase(); |
| 332 | |
| 333 | if ( email[ paramName ] ) |
| 334 | { |
| 335 | i > 0 && retval.push( ',' ); |
| 336 | retval.push( '\'', escapeSingleQuote( encodeURIComponent( email[ paramName ] ) ), '\''); |
| 337 | } |
| 338 | } |
| 339 | retval.push( ')' ); |
| 340 | return retval.join( '' ); |
| 341 | } |
| 342 | |
| 343 | function protectEmailAddressAsEncodedString( address ) |
| 344 | { |
| 345 | var charCode, |
| 346 | length = address.length, |
| 347 | encodedChars = []; |
| 348 | for ( var i = 0; i < length; i++ ) |
| 349 | { |
| 350 | charCode = address.charCodeAt( i ); |
| 351 | encodedChars.push( charCode ); |
| 352 | } |
| 353 | return 'String.fromCharCode(' + encodedChars.join( ',' ) + ')'; |
| 354 | } |
| 355 | |
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 | | } |
| 1178 | case '' : |
| 1179 | case 'encode' : |
| 1180 | { |
| 1181 | var subject = encodeURIComponent( email.subject || '' ), |
| 1182 | body = encodeURIComponent( email.body || '' ); |
| 1183 | |
| 1184 | // Build the e-mail parameters first. |
| 1185 | var argList = []; |
| 1186 | subject && argList.push( 'subject=' + subject ); |
| 1187 | body && argList.push( 'body=' + body ); |
| 1188 | argList = argList.length ? '?' + argList.join( '&' ) : ''; |
| 1189 | |
| 1190 | if ( emailProtection == 'encode' ) |
| 1191 | { |
| 1192 | linkHref = [ 'javascript:void(location.href=\'mailto:\'+', |
| 1193 | protectEmailAddressAsEncodedString( address ) ]; |
| 1194 | // parameters are optional. |
| 1195 | argList && linkHref.push( '+\'', escapeSingleQuote( argList ), '\'' ); |
| 1196 | |
| 1197 | linkHref.push( ')' ); |
| 1198 | } |
| 1199 | else |
| 1200 | linkHref = [ 'mailto:', address, argList ]; |
| 1201 | |
| 1202 | break; |
| 1203 | } |
| 1204 | default : |
| 1205 | { |
| 1206 | // Separating name and domain. |
| 1207 | var nameAndDomain = address.split( '@', 2 ); |
| 1208 | email.name = nameAndDomain[ 0 ]; |
| 1209 | email.domain = nameAndDomain[ 1 ]; |
| 1210 | |
| 1211 | linkHref = [ 'javascript:', protectEmailLinkAsFunction( email ) ]; |
| 1212 | } |
| 1213 | } |
1221 | | } ); |
| 1361 | } ) |
| 1362 | |
| 1363 | /** |
| 1364 | * @name CKEDITOR.config.mailProtection |
| 1365 | * The e-mail address anti-spam protection option. |
| 1366 | * @type String |
| 1367 | * Two forms of protection could be choosed from : |
| 1368 | * 1. The whole address parts ( name, domain with any other query string ) are assembled into a |
| 1369 | * function call pattern which invoke you own provided function, with the specified arguments. |
| 1370 | * 2. Only the e-mail address is obfuscated into their corresponding ASC2 values, replacement are |
| 1371 | * done by a String.fromCharCode() call. |
| 1372 | * Note: Both approaches require JavaScript to be enabled. |
| 1373 | * @default false |
| 1374 | * @example |
| 1375 | * config.mailProtection = ''; |
| 1376 | * // href="mailto:tester@ckeditor.com?subject=subject&body=body" |
| 1377 | * config.mailProtection = 'encode'; |
| 1378 | * // 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>" |
| 1379 | * config.mailProtection = 'mt(NAME,DOMAIN,SUBJECT,BODY)'; |
| 1380 | * // href="javascript:mt('tester','ckeditor.com','subject','body')" |
| 1381 | */ |