return;\r
\r
popupFeatures = popupFeatures.getElement();\r
+ popupFeatures.hide();\r
+ targetName.setValue( '' );\r
+\r
+ switch ( value )\r
+ {\r
+ case 'frame' :\r
+ targetName.setLabel( editor.lang.link.targetFrameName );\r
+ targetName.getElement().show();\r
+ break;\r
+ case 'popup' :\r
+ popupFeatures.show();\r
+ targetName.setLabel( editor.lang.link.targetPopupName );\r
+ targetName.getElement().show();\r
+ break;\r
+ default :\r
+ targetName.setValue( value );\r
+ targetName.getElement().hide();\r
+ break;\r
+ }\r
\r
- if ( value == 'popup' )\r
- {\r
- popupFeatures.show();\r
- targetName.setLabel( editor.lang.link.targetPopupName );\r
- }\r
- else\r
- {\r
- popupFeatures.hide();\r
- targetName.setLabel( editor.lang.link.targetFrameName );\r
- this.getDialog().setValueOf( 'target', 'linkTargetName', value.charAt( 0 ) == '_' ? value : '' );\r
- }\r
};\r
\r
// Handles the event when the "Type" selection box is changed.\r
};\r
\r
// Loads the parameters in a selected link to the link dialog fields.\r
- var emailRegex = /^mailto:([^?]+)(?:\?(.+))?$/,\r
+ var javascriptProtocolRegex = /^javascript:/,\r
+ emailRegex = /^mailto:([^?]+)(?:\?(.+))?$/,\r
emailSubjectRegex = /subject=([^;?:@&=$,\/]*)/,\r
emailBodyRegex = /body=([^;?:@&=$,\/]*)/,\r
anchorRegex = /^#(.*)$/,\r
- urlRegex = /^(?!javascript)((?:http|https|ftp|news):\/\/)?(.*)$/,\r
+ urlRegex = /^((?:http|https|ftp|news):\/\/)?(.*)$/,\r
selectableTargets = /^(_(?:self|top|parent|blank))$/,\r
encodedEmailLinkRegex = /^javascript:void\(location\.href='mailto:'\+String\.fromCharCode\(([^)]+)\)(?:\+'(.*)')?\)$/,\r
functionCallProtectedEmailLinkRegex = /^javascript:([^(]+)\(([^)]+)\)$/;\r
var parseLink = function( editor, element )\r
{\r
var href = element ? ( element.getAttribute( '_cke_saved_href' ) || element.getAttribute( 'href' ) ) : '',\r
+ javascriptMatch,\r
emailMatch,\r
anchorMatch,\r
urlMatch,\r
retval = {};\r
\r
- if ( ( anchorMatch = href.match( anchorRegex ) ) )\r
+ if ( ( javascriptMatch = href.match( javascriptProtocolRegex ) ) )\r
{\r
- retval.type = 'anchor';\r
- retval.anchor = {};\r
- retval.anchor.name = retval.anchor.id = anchorMatch[1];\r
- }\r
- // urlRegex matches empty strings, so need to check for href as well.\r
- else if ( href && ( urlMatch = href.match( urlRegex ) ) )\r
- {\r
- retval.type = 'url';\r
- retval.url = {};\r
- retval.url.protocol = urlMatch[1];\r
- retval.url.url = urlMatch[2];\r
- }\r
- // Protected email link as encoded string.\r
- else if ( !emailProtection || emailProtection == 'encode' )\r
- {\r
- if( emailProtection == 'encode' )\r
+ if ( emailProtection == 'encode' )\r
{\r
href = href.replace( encodedEmailLinkRegex,\r
function ( match, protectedAddress, rest )\r
return 'mailto:' +\r
String.fromCharCode.apply( String, protectedAddress.split( ',' ) ) +\r
( rest && unescapeSingleQuote( rest ) );\r
- } );\r
+ });\r
}\r
+ // Protected email link as function call.\r
+ else if ( emailProtection )\r
+ {\r
+ href.replace( functionCallProtectedEmailLinkRegex, function( match, funcName, funcArgs )\r
+ {\r
+ if ( funcName == compiledProtectionFunction.name )\r
+ {\r
+ retval.type = 'email';\r
+ var email = retval.email = {};\r
\r
- emailMatch = href.match( emailRegex );\r
+ var paramRegex = /[^,\s]+/g,\r
+ paramQuoteRegex = /(^')|('$)/g,\r
+ paramsMatch = funcArgs.match( paramRegex ),\r
+ paramsMatchLength = paramsMatch.length,\r
+ paramName,\r
+ paramVal;\r
\r
- if( emailMatch )\r
+ for ( var i = 0; i < paramsMatchLength; i++ )\r
+ {\r
+ paramVal = decodeURIComponent( unescapeSingleQuote( paramsMatch[ i ].replace( paramQuoteRegex, '' ) ) );\r
+ paramName = compiledProtectionFunction.params[ i ].toLowerCase();\r
+ email[ paramName ] = paramVal;\r
+ }\r
+ email.address = [ email.name, email.domain ].join( '@' );\r
+ }\r
+ } );\r
+ }\r
+ }\r
+\r
+ if ( !retval.type )\r
+ {\r
+ if ( ( anchorMatch = href.match( anchorRegex ) ) )\r
+ {\r
+ retval.type = 'anchor';\r
+ retval.anchor = {};\r
+ retval.anchor.name = retval.anchor.id = anchorMatch[1];\r
+ }\r
+ // Protected email link as encoded string.\r
+ else if ( ( emailMatch = href.match( emailRegex ) ) )\r
{\r
var subjectMatch = href.match( emailSubjectRegex ),\r
bodyMatch = href.match( emailBodyRegex );\r
subjectMatch && ( email.subject = decodeURIComponent( subjectMatch[ 1 ] ) );\r
bodyMatch && ( email.body = decodeURIComponent( bodyMatch[ 1 ] ) );\r
}\r
- }\r
- // Protected email link as function call.\r
- else if( emailProtection )\r
- {\r
- href.replace( functionCallProtectedEmailLinkRegex, function( match, funcName, funcArgs )\r
+ // urlRegex matches empty strings, so need to check for href as well.\r
+ else if ( href && ( urlMatch = href.match( urlRegex ) ) )\r
{\r
- if( funcName == compiledProtectionFunction.name )\r
- {\r
- retval.type = 'email';\r
- var email = retval.email = {};\r
-\r
- var paramRegex = /[^,\s]+/g,\r
- paramQuoteRegex = /(^')|('$)/g,\r
- paramsMatch = funcArgs.match( paramRegex ),\r
- paramsMatchLength = paramsMatch.length,\r
- paramName,\r
- paramVal;\r
-\r
- for ( var i = 0; i < paramsMatchLength; i++ )\r
- {\r
- paramVal = decodeURIComponent( unescapeSingleQuote( paramsMatch[ i ].replace( paramQuoteRegex, '' ) ) );\r
- paramName = compiledProtectionFunction.params[ i ].toLowerCase();\r
- email[ paramName ] = paramVal;\r
- }\r
- email.address = [ email.name, email.domain ].join( '@' );\r
- }\r
- } );\r
+ retval.type = 'url';\r
+ retval.url = {};\r
+ retval.url.protocol = urlMatch[1];\r
+ retval.url.url = urlMatch[2];\r
+ }\r
+ else\r
+ retval.type = 'url';\r
}\r
- else\r
- retval.type = 'url';\r
\r
// Load target and popup settings.\r
if ( element )\r
realAnchors = new CKEDITOR.dom.nodeList( editor.document.$.anchors ),\r
anchors = retval.anchors = [];\r
\r
- for( var i = 0; i < elements.count() ; i++ )\r
+ for ( var i = 0; i < elements.count() ; i++ )\r
{\r
var item = elements.getItem( i );\r
if ( item.getAttribute( '_cke_realelement' ) && item.getAttribute( '_cke_real_element_type' ) == 'anchor' )\r
var emailProtection = editor.config.emailProtection || '';\r
\r
// Compile the protection function pattern.\r
- if( emailProtection && emailProtection != 'encode' )\r
+ if ( emailProtection && emailProtection != 'encode' )\r
{\r
var compiledProtectionFunction = {};\r
\r
},\r
commit : function( data )\r
{\r
+ // IE will not trigger the onChange event if the mouse has been used\r
+ // to carry all the operations #4724\r
+ this.onChange();\r
+\r
if ( !data.url )\r
data.url = {};\r
\r
else\r
{\r
// We're only editing an existing link, so just overwrite the attributes.\r
- var element = this._.selectedElement;\r
+ var element = this._.selectedElement,\r
+ href = element.getAttribute( '_cke_saved_href' ),\r
+ textView = element.getHtml();\r
\r
// IE BUG: Setting the name attribute to an existing link doesn't work.\r
// Must re-create the link from weired syntax to workaround.\r
\r
element.setAttributes( attributes );\r
element.removeAttributes( removeAttributes );\r
-\r
+ // Update text view when user changes protocol #4612.\r
+ if (href == textView)\r
+ element.setHtml( attributes._cke_saved_href );\r
// Make the element display as an anchor if a name has been set.\r
if ( element.getAttribute( 'name' ) )\r
element.addClass( 'cke_anchor' );\r
});\r
\r
/**\r
- * The e-mail address anti-spam protection option.\r
+ * The e-mail address anti-spam protection option. The protection will be\r
+ * applied when creating or modifying e-mail links through the editor interface.<br>\r
+ * Two methods of protection can be choosed:\r
+ * <ol> <li>The e-mail parts (name, domain and any other query string) are\r
+ * assembled into a function call pattern. Such function must be\r
+ * provided by the developer in the pages that will use the contents.\r
+ * <li>Only the e-mail address is obfuscated into a special string that\r
+ * has no meaning for humans or spam bots, but which is properly\r
+ * rendered and accepted by the browser.</li></ol>\r
+ * Both approaches require JavaScript to be enabled.\r
* @name CKEDITOR.config.emailProtection\r
- * @type {String}\r
- * Two forms of protection could be choosed from :\r
- * 1. The whole address parts ( name, domain with any other query string ) are assembled into a\r
- * function call pattern which invoke you own provided function, with the specified arguments.\r
- * 2. Only the e-mail address is obfuscated into unicode code point sequences, replacement are\r
- * done by a String.fromCharCode() call.\r
- * Note: Both approaches require JavaScript to be enabled.\r
- * @default ''\r
+ * @since 3.1\r
+ * @type String\r
+ * @default '' (empty string = disabled)\r
+ * @example\r
+ * // href="mailto:tester@ckeditor.com?subject=subject&body=body"\r
+ * config.emailProtection = '';\r
+ * @example\r
+ * // 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>"\r
+ * config.emailProtection = 'encode';\r
* @example\r
- * config.emailProtection = '';\r
- * // href="mailto:tester@ckeditor.com?subject=subject&body=body"\r
- * config.emailProtection = 'encode';\r
- * // 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>"\r
- * config.emailProtection = 'mt(NAME,DOMAIN,SUBJECT,BODY)';\r
- * // href="javascript:mt('tester','ckeditor.com','subject','body')"\r
+ * // href="javascript:mt('tester','ckeditor.com','subject','body')"\r
+ * config.emailProtection = 'mt(NAME,DOMAIN,SUBJECT,BODY)';\r
*/\r