X-Git-Url: https://jasonwoof.com/gitweb/?a=blobdiff_plain;f=_source%2Fplugins%2Flink%2Fdialogs%2Flink.js;h=c7388ca639efad04b417e2349785a9e4f68305dc;hb=refs%2Ftags%2Fv3.2;hp=283c5f77bf82ea0c7dcd5ad0193e0b796264922e;hpb=ea7e3453c7b0f023b050aca6d9f83ab372860d91;p=ckeditor.git
diff --git a/_source/plugins/link/dialogs/link.js b/_source/plugins/link/dialogs/link.js
index 283c5f7..c7388ca 100644
--- a/_source/plugins/link/dialogs/link.js
+++ b/_source/plugins/link/dialogs/link.js
@@ -1,5 +1,5 @@
/*
-Copyright (c) 2003-2009, CKSource - Frederico Knabben. All rights reserved.
+Copyright (c) 2003-2010, CKSource - Frederico Knabben. All rights reserved.
For licensing, see LICENSE.html or http://ckeditor.com/license
*/
@@ -17,18 +17,26 @@ CKEDITOR.dialog.add( 'link', function( editor )
return;
popupFeatures = popupFeatures.getElement();
+ popupFeatures.hide();
+ targetName.setValue( '' );
+
+ switch ( value )
+ {
+ case 'frame' :
+ targetName.setLabel( editor.lang.link.targetFrameName );
+ targetName.getElement().show();
+ break;
+ case 'popup' :
+ popupFeatures.show();
+ targetName.setLabel( editor.lang.link.targetPopupName );
+ targetName.getElement().show();
+ break;
+ default :
+ targetName.setValue( value );
+ targetName.getElement().hide();
+ break;
+ }
- if ( value == 'popup' )
- {
- popupFeatures.show();
- targetName.setLabel( editor.lang.link.targetPopupName );
- }
- else
- {
- popupFeatures.hide();
- targetName.setLabel( editor.lang.link.targetFrameName );
- this.getDialog().setValueOf( 'target', 'linkTargetName', value.charAt( 0 ) == '_' ? value : '' );
- }
};
// Handles the event when the "Type" selection box is changed.
@@ -37,7 +45,8 @@ CKEDITOR.dialog.add( 'link', function( editor )
var dialog = this.getDialog(),
partIds = [ 'urlOptions', 'anchorOptions', 'emailOptions' ],
typeValue = this.getValue(),
- uploadInitiallyHidden = dialog.definition.getContents( 'upload' ).hidden;
+ uploadTab = dialog.definition.getContents( 'upload' ),
+ uploadInitiallyHidden = uploadTab && uploadTab.hidden;
if ( typeValue == 'url' )
{
@@ -68,12 +77,15 @@ CKEDITOR.dialog.add( 'link', function( editor )
};
// Loads the parameters in a selected link to the link dialog fields.
- var emailRegex = /^mailto:([^?]+)(?:\?(.+))?$/,
+ var javascriptProtocolRegex = /^javascript:/,
+ emailRegex = /^mailto:([^?]+)(?:\?(.+))?$/,
emailSubjectRegex = /subject=([^;?:@&=$,\/]*)/,
emailBodyRegex = /body=([^;?:@&=$,\/]*)/,
anchorRegex = /^#(.*)$/,
urlRegex = /^((?:http|https|ftp|news):\/\/)?(.*)$/,
- selectableTargets = /^(_(?:self|top|parent|blank))$/;
+ selectableTargets = /^(_(?:self|top|parent|blank))$/,
+ encodedEmailLinkRegex = /^javascript:void\(location\.href='mailto:'\+String\.fromCharCode\(([^)]+)\)(?:\+'(.*)')?\)$/,
+ functionCallProtectedEmailLinkRegex = /^javascript:([^(]+)\(([^)]+)\)$/;
var popupRegex =
/\s*window.open\(\s*this\.href\s*,\s*(?:'([^']*)'|null)\s*,\s*'([^']*)'\s*\)\s*;\s*return\s*false;*\s*/;
@@ -82,44 +94,84 @@ CKEDITOR.dialog.add( 'link', function( editor )
var parseLink = function( editor, element )
{
var href = element ? ( element.getAttribute( '_cke_saved_href' ) || element.getAttribute( 'href' ) ) : '',
- emailMatch = '',
- anchorMatch = '',
- urlMatch = false,
+ javascriptMatch,
+ emailMatch,
+ anchorMatch,
+ urlMatch,
retval = {};
- if ( href )
+ if ( ( javascriptMatch = href.match( javascriptProtocolRegex ) ) )
{
- emailMatch = href.match( emailRegex );
- anchorMatch = href.match( anchorRegex );
- urlMatch = href.match( urlRegex );
- }
+ if ( emailProtection == 'encode' )
+ {
+ href = href.replace( encodedEmailLinkRegex,
+ function ( match, protectedAddress, rest )
+ {
+ return 'mailto:' +
+ String.fromCharCode.apply( String, protectedAddress.split( ',' ) ) +
+ ( rest && unescapeSingleQuote( rest ) );
+ });
+ }
+ // Protected email link as function call.
+ else if ( emailProtection )
+ {
+ href.replace( functionCallProtectedEmailLinkRegex, function( match, funcName, funcArgs )
+ {
+ if ( funcName == compiledProtectionFunction.name )
+ {
+ retval.type = 'email';
+ var email = retval.email = {};
- // Load the link type and URL.
- if ( emailMatch )
- {
- var subjectMatch = href.match( emailSubjectRegex ),
- bodyMatch = href.match( emailBodyRegex );
- retval.type = 'email';
- retval.email = {};
- retval.email.address = emailMatch[1];
- subjectMatch && ( retval.email.subject = decodeURIComponent( subjectMatch[1] ) );
- bodyMatch && ( retval.email.body = decodeURIComponent( bodyMatch[1] ) );
- }
- else if ( anchorMatch )
- {
- retval.type = 'anchor';
- retval.anchor = {};
- retval.anchor.name = retval.anchor.id = anchorMatch[1];
+ var paramRegex = /[^,\s]+/g,
+ paramQuoteRegex = /(^')|('$)/g,
+ paramsMatch = funcArgs.match( paramRegex ),
+ paramsMatchLength = paramsMatch.length,
+ paramName,
+ paramVal;
+
+ for ( var i = 0; i < paramsMatchLength; i++ )
+ {
+ paramVal = decodeURIComponent( unescapeSingleQuote( paramsMatch[ i ].replace( paramQuoteRegex, '' ) ) );
+ paramName = compiledProtectionFunction.params[ i ].toLowerCase();
+ email[ paramName ] = paramVal;
+ }
+ email.address = [ email.name, email.domain ].join( '@' );
+ }
+ } );
+ }
}
- else if ( href && urlMatch ) // urlRegex matches empty strings, so need to check for href as well.
+
+ if ( !retval.type )
{
- retval.type = 'url';
- retval.url = {};
- retval.url.protocol = urlMatch[1];
- retval.url.url = urlMatch[2];
+ if ( ( anchorMatch = href.match( anchorRegex ) ) )
+ {
+ retval.type = 'anchor';
+ retval.anchor = {};
+ retval.anchor.name = retval.anchor.id = anchorMatch[1];
+ }
+ // Protected email link as encoded string.
+ else if ( ( emailMatch = href.match( emailRegex ) ) )
+ {
+ var subjectMatch = href.match( emailSubjectRegex ),
+ bodyMatch = href.match( emailBodyRegex );
+
+ retval.type = 'email';
+ var email = ( retval.email = {} );
+ email.address = emailMatch[ 1 ];
+ subjectMatch && ( email.subject = decodeURIComponent( subjectMatch[ 1 ] ) );
+ bodyMatch && ( email.body = decodeURIComponent( bodyMatch[ 1 ] ) );
+ }
+ // urlRegex matches empty strings, so need to check for href as well.
+ else if ( href && ( urlMatch = href.match( urlRegex ) ) )
+ {
+ retval.type = 'url';
+ retval.url = {};
+ retval.url.protocol = urlMatch[1];
+ retval.url.url = urlMatch[2];
+ }
+ else
+ retval.type = 'url';
}
- else
- retval.type = 'url';
// Load target and popup settings.
if ( element )
@@ -186,7 +238,7 @@ CKEDITOR.dialog.add( 'link', function( editor )
realAnchors = new CKEDITOR.dom.nodeList( editor.document.$.anchors ),
anchors = retval.anchors = [];
- for( var i = 0; i < elements.count() ; i++ )
+ for ( var i = 0; i < elements.count() ; i++ )
{
var item = elements.getItem( i );
if ( item.getAttribute( '_cke_realelement' ) && item.getAttribute( '_cke_real_element_type' ) == 'anchor' )
@@ -244,6 +296,72 @@ CKEDITOR.dialog.add( 'link', function( editor )
return commitParams.call( this, 'adv', data );
};
+ function unescapeSingleQuote( str )
+ {
+ return str.replace( /\\'/g, '\'' );
+ }
+
+ function escapeSingleQuote( str )
+ {
+ return str.replace( /'/g, '\\$&' );
+ }
+
+ var emailProtection = editor.config.emailProtection || '';
+
+ // Compile the protection function pattern.
+ if ( emailProtection && emailProtection != 'encode' )
+ {
+ var compiledProtectionFunction = {};
+
+ emailProtection.replace( /^([^(]+)\(([^)]+)\)$/, function( match, funcName, params )
+ {
+ compiledProtectionFunction.name = funcName;
+ compiledProtectionFunction.params = [];
+ params.replace( /[^,\s]+/g, function( param )
+ {
+ compiledProtectionFunction.params.push( param );
+ } );
+ } );
+ }
+
+ function protectEmailLinkAsFunction( email )
+ {
+ var retval,
+ name = compiledProtectionFunction.name,
+ params = compiledProtectionFunction.params,
+ paramName,
+ paramValue;
+
+ retval = [ name, '(' ];
+ for ( var i = 0; i < params.length; i++ )
+ {
+ paramName = params[ i ].toLowerCase();
+ paramValue = email[ paramName ];
+
+ i > 0 && retval.push( ',' );
+ retval.push( '\'',
+ paramValue ?
+ escapeSingleQuote( encodeURIComponent( email[ paramName ] ) )
+ : '',
+ '\'');
+ }
+ retval.push( ')' );
+ return retval.join( '' );
+ }
+
+ function protectEmailAddressAsEncodedString( address )
+ {
+ var charCode,
+ length = address.length,
+ encodedChars = [];
+ for ( var i = 0; i < length; i++ )
+ {
+ charCode = address.charCodeAt( i );
+ encodedChars.push( charCode );
+ }
+ return 'String.fromCharCode(' + encodedChars.join( ',' ) + ')';
+ }
+
return {
title : editor.lang.link.title,
minWidth : 350,
@@ -262,7 +380,7 @@ CKEDITOR.dialog.add( 'link', function( editor )
'default' : 'url',
items :
[
- [ editor.lang.common.url, 'url' ],
+ [ editor.lang.link.toUrl, 'url' ],
[ editor.lang.link.toAnchor, 'anchor' ],
[ editor.lang.link.toEmail, 'email' ]
],
@@ -304,7 +422,7 @@ CKEDITOR.dialog.add( 'link', function( editor )
setup : function( data )
{
if ( data.url )
- this.setValue( data.url.protocol );
+ this.setValue( data.url.protocol || '' );
},
commit : function( data )
{
@@ -318,6 +436,7 @@ CKEDITOR.dialog.add( 'link', function( editor )
type : 'text',
id : 'url',
label : editor.lang.common.url,
+ required: true,
onLoad : function ()
{
this.allowOnChange = true;
@@ -367,13 +486,13 @@ CKEDITOR.dialog.add( 'link', function( editor )
this.setValue( data.url.url );
this.allowOnChange = true;
- var linkType = this.getDialog().getContentElement( 'info', 'linkType' );
- if ( linkType && linkType.getValue() == 'url' )
- this.select();
-
},
commit : function( data )
{
+ // IE will not trigger the onChange event if the mouse has been used
+ // to carry all the operations #4724
+ this.onChange();
+
if ( !data.url )
data.url = {};
@@ -406,105 +525,110 @@ CKEDITOR.dialog.add( 'link', function( editor )
children :
[
{
- type : 'html',
+ type : 'fieldset',
id : 'selectAnchorText',
- html : CKEDITOR.tools.htmlEncode( editor.lang.link.selectAnchor ),
+ label : editor.lang.link.selectAnchor,
setup : function( data )
{
if ( data.anchors.length > 0 )
this.getElement().show();
else
this.getElement().hide();
- }
- },
- {
- type : 'html',
- id : 'noAnchors',
- style : 'text-align: center;',
- html : '
' + CKEDITOR.tools.htmlEncode( editor.lang.link.noAnchors ) + '
',
- setup : function( data )
- {
- if ( data.anchors.length < 1 )
- this.getElement().show();
- else
- this.getElement().hide();
- }
- },
- {
- type : 'hbox',
- id : 'selectAnchor',
+ },
children :
[
{
- type : 'select',
- id : 'anchorName',
- 'default' : '',
- label : editor.lang.link.anchorName,
- style : 'width: 100%;',
- items :
+ type : 'hbox',
+ id : 'selectAnchor',
+ children :
[
- [ '' ]
- ],
- setup : function( data )
- {
- this.clear();
- this.add( '' );
- for ( var i = 0 ; i < data.anchors.length ; i++ )
{
- if ( data.anchors[i].name )
- this.add( data.anchors[i].name );
+ type : 'select',
+ id : 'anchorName',
+ 'default' : '',
+ label : editor.lang.link.anchorName,
+ style : 'width: 100%;',
+ items :
+ [
+ [ '' ]
+ ],
+ setup : function( data )
+ {
+ this.clear();
+ this.add( '' );
+ for ( var i = 0 ; i < data.anchors.length ; i++ )
+ {
+ if ( data.anchors[i].name )
+ this.add( data.anchors[i].name );
+ }
+
+ if ( data.anchor )
+ this.setValue( data.anchor.name );
+
+ var linkType = this.getDialog().getContentElement( 'info', 'linkType' );
+ if ( linkType && linkType.getValue() == 'email' )
+ this.focus();
+ },
+ commit : function( data )
+ {
+ if ( !data.anchor )
+ data.anchor = {};
+
+ data.anchor.name = this.getValue();
+ }
+ },
+ {
+ type : 'select',
+ id : 'anchorId',
+ 'default' : '',
+ label : editor.lang.link.anchorId,
+ style : 'width: 100%;',
+ items :
+ [
+ [ '' ]
+ ],
+ setup : function( data )
+ {
+ this.clear();
+ this.add( '' );
+ for ( var i = 0 ; i < data.anchors.length ; i++ )
+ {
+ if ( data.anchors[i].id )
+ this.add( data.anchors[i].id );
+ }
+
+ if ( data.anchor )
+ this.setValue( data.anchor.id );
+ },
+ commit : function( data )
+ {
+ if ( !data.anchor )
+ data.anchor = {};
+
+ data.anchor.id = this.getValue();
+ }
}
-
- if ( data.anchor )
- this.setValue( data.anchor.name );
-
- var linkType = this.getDialog().getContentElement( 'info', 'linkType' );
- if ( linkType && linkType.getValue() == 'email' )
- this.focus();
- },
- commit : function( data )
- {
- if ( !data.anchor )
- data.anchor = {};
-
- data.anchor.name = this.getValue();
- }
- },
- {
- type : 'select',
- id : 'anchorId',
- 'default' : '',
- label : editor.lang.link.anchorId,
- style : 'width: 100%;',
- items :
- [
- [ '' ]
],
setup : function( data )
{
- this.clear();
- this.add( '' );
- for ( var i = 0 ; i < data.anchors.length ; i++ )
- {
- if ( data.anchors[i].id )
- this.add( data.anchors[i].id );
- }
-
- if ( data.anchor )
- this.setValue( data.anchor.id );
- },
- commit : function( data )
- {
- if ( !data.anchor )
- data.anchor = {};
-
- data.anchor.id = this.getValue();
+ if ( data.anchors.length > 0 )
+ this.getElement().show();
+ else
+ this.getElement().hide();
}
}
- ],
+ ]
+ },
+ {
+ type : 'html',
+ id : 'noAnchors',
+ style : 'text-align: center;',
+ html : '' + CKEDITOR.tools.htmlEncode( editor.lang.link.noAnchors ) + '
',
+ // Focus the first element defined in above html.
+ focus : true,
setup : function( data )
{
- if ( data.anchors.length > 0 )
+ if ( data.anchors.length < 1 )
this.getElement().show();
else
this.getElement().hide();
@@ -527,6 +651,7 @@ CKEDITOR.dialog.add( 'link', function( editor )
type : 'text',
id : 'emailAddress',
label : editor.lang.link.emailAddress,
+ required : true,
validate : function()
{
var dialog = this.getDialog();
@@ -614,18 +739,18 @@ CKEDITOR.dialog.add( 'link', function( editor )
{
type : 'select',
id : 'linkTargetType',
- label : editor.lang.link.target,
+ label : editor.lang.common.target,
'default' : 'notSet',
style : 'width : 100%;',
'items' :
[
- [ editor.lang.link.targetNotSet, 'notSet' ],
+ [ editor.lang.common.notSet, 'notSet' ],
[ editor.lang.link.targetFrame, 'frame' ],
[ editor.lang.link.targetPopup, 'popup' ],
- [ editor.lang.link.targetNew, '_blank' ],
- [ editor.lang.link.targetTop, '_top' ],
- [ editor.lang.link.targetSelf, '_self' ],
- [ editor.lang.link.targetParent, '_parent' ]
+ [ editor.lang.common.targetNew, '_blank' ],
+ [ editor.lang.common.targetTop, '_top' ],
+ [ editor.lang.common.targetSelf, '_self' ],
+ [ editor.lang.common.targetParent, '_parent' ]
],
onChange : targetChanged,
setup : function( data )
@@ -670,145 +795,148 @@ CKEDITOR.dialog.add( 'link', function( editor )
children :
[
{
- type : 'html',
- html : CKEDITOR.tools.htmlEncode( editor.lang.link.popupFeatures )
- },
- {
- type : 'hbox',
+ type : 'fieldset',
+ label : editor.lang.link.popupFeatures,
children :
[
{
- type : 'checkbox',
- id : 'resizable',
- label : editor.lang.link.popupResizable,
- setup : setupPopupParams,
- commit : commitPopupParams
- },
- {
- type : 'checkbox',
- id : 'status',
- label : editor.lang.link.popupStatusBar,
- setup : setupPopupParams,
- commit : commitPopupParams
-
- }
- ]
- },
- {
- type : 'hbox',
- children :
- [
- {
- type : 'checkbox',
- id : 'location',
- label : editor.lang.link.popupLocationBar,
- setup : setupPopupParams,
- commit : commitPopupParams
+ type : 'hbox',
+ children :
+ [
+ {
+ type : 'checkbox',
+ id : 'resizable',
+ label : editor.lang.link.popupResizable,
+ setup : setupPopupParams,
+ commit : commitPopupParams
+ },
+ {
+ type : 'checkbox',
+ id : 'status',
+ label : editor.lang.link.popupStatusBar,
+ setup : setupPopupParams,
+ commit : commitPopupParams
+ }
+ ]
},
{
- type : 'checkbox',
- id : 'toolbar',
- label : editor.lang.link.popupToolbar,
- setup : setupPopupParams,
- commit : commitPopupParams
+ type : 'hbox',
+ children :
+ [
+ {
+ type : 'checkbox',
+ id : 'location',
+ label : editor.lang.link.popupLocationBar,
+ setup : setupPopupParams,
+ commit : commitPopupParams
- }
- ]
- },
- {
- type : 'hbox',
- children :
- [
- {
- type : 'checkbox',
- id : 'menubar',
- label : editor.lang.link.popupMenuBar,
- setup : setupPopupParams,
- commit : commitPopupParams
+ },
+ {
+ type : 'checkbox',
+ id : 'toolbar',
+ label : editor.lang.link.popupToolbar,
+ setup : setupPopupParams,
+ commit : commitPopupParams
+ }
+ ]
},
{
- type : 'checkbox',
- id : 'fullscreen',
- label : editor.lang.link.popupFullScreen,
- setup : setupPopupParams,
- commit : commitPopupParams
+ type : 'hbox',
+ children :
+ [
+ {
+ type : 'checkbox',
+ id : 'menubar',
+ label : editor.lang.link.popupMenuBar,
+ setup : setupPopupParams,
+ commit : commitPopupParams
- }
- ]
- },
- {
- type : 'hbox',
- children :
- [
- {
- type : 'checkbox',
- id : 'scrollbars',
- label : editor.lang.link.popupScrollBars,
- setup : setupPopupParams,
- commit : commitPopupParams
+ },
+ {
+ type : 'checkbox',
+ id : 'fullscreen',
+ label : editor.lang.link.popupFullScreen,
+ setup : setupPopupParams,
+ commit : commitPopupParams
+ }
+ ]
},
{
- type : 'checkbox',
- id : 'dependent',
- label : editor.lang.link.popupDependent,
- setup : setupPopupParams,
- commit : commitPopupParams
+ type : 'hbox',
+ children :
+ [
+ {
+ type : 'checkbox',
+ id : 'scrollbars',
+ label : editor.lang.link.popupScrollBars,
+ setup : setupPopupParams,
+ commit : commitPopupParams
- }
- ]
- },
- {
- type : 'hbox',
- children :
- [
- {
- type : 'text',
- widths : [ '30%', '70%' ],
- labelLayout : 'horizontal',
- label : editor.lang.link.popupWidth,
- id : 'width',
- setup : setupPopupParams,
- commit : commitPopupParams
+ },
+ {
+ type : 'checkbox',
+ id : 'dependent',
+ label : editor.lang.link.popupDependent,
+ setup : setupPopupParams,
+ commit : commitPopupParams
+ }
+ ]
},
{
- type : 'text',
- labelLayout : 'horizontal',
- widths : [ '55%', '45%' ],
- label : editor.lang.link.popupLeft,
- id : 'left',
- setup : setupPopupParams,
- commit : commitPopupParams
-
- }
- ]
- },
- {
- type : 'hbox',
- children :
- [
- {
- type : 'text',
- labelLayout : 'horizontal',
- widths : [ '30%', '70%' ],
- label : editor.lang.link.popupHeight,
- id : 'height',
- setup : setupPopupParams,
- commit : commitPopupParams
+ type : 'hbox',
+ children :
+ [
+ {
+ type : 'text',
+ widths : [ '30%', '70%' ],
+ labelLayout : 'horizontal',
+ label : editor.lang.link.popupWidth,
+ id : 'width',
+ setup : setupPopupParams,
+ commit : commitPopupParams
+
+ },
+ {
+ type : 'text',
+ labelLayout : 'horizontal',
+ widths : [ '55%', '45%' ],
+ label : editor.lang.link.popupLeft,
+ id : 'left',
+ setup : setupPopupParams,
+ commit : commitPopupParams
+ }
+ ]
},
{
- type : 'text',
- labelLayout : 'horizontal',
- label : editor.lang.link.popupTop,
- widths : [ '55%', '45%' ],
- id : 'top',
- setup : setupPopupParams,
- commit : commitPopupParams
+ type : 'hbox',
+ children :
+ [
+ {
+ type : 'text',
+ labelLayout : 'horizontal',
+ widths : [ '30%', '70%' ],
+ label : editor.lang.link.popupHeight,
+ id : 'height',
+ setup : setupPopupParams,
+ commit : commitPopupParams
+
+ },
+ {
+ type : 'text',
+ labelLayout : 'horizontal',
+ label : editor.lang.link.popupTop,
+ widths : [ '55%', '45%' ],
+ id : 'top',
+ setup : setupPopupParams,
+ commit : commitPopupParams
+ }
+ ]
}
]
}
@@ -871,7 +999,7 @@ CKEDITOR.dialog.add( 'link', function( editor )
style : 'width:110px',
items :
[
- [ editor.lang.link.langDirNotSet, '' ],
+ [ editor.lang.common.notSet, '' ],
[ editor.lang.link.langDirLTR, 'ltr' ],
[ editor.lang.link.langDirRTL, 'rtl' ]
],
@@ -1040,7 +1168,8 @@ CKEDITOR.dialog.add( 'link', function( editor )
var attributes = { href : 'javascript:void(0)/*' + CKEDITOR.tools.getNextNumber() + '*/' },
removeAttributes = [],
data = { href : attributes.href },
- me = this, editor = this.getParentEditor();
+ me = this,
+ editor = this.getParentEditor();
this.commitContent( data );
@@ -1058,21 +1187,52 @@ CKEDITOR.dialog.add( 'link', function( editor )
attributes._cke_saved_href = '#' + ( name || id || '' );
break;
case 'email':
- var address = ( data.email && data.email.address ),
- subject = ( data.email && encodeURIComponent( data.email.subject || '' ) ),
- body = ( data.email && encodeURIComponent( data.email.body || '' ) ),
- linkList = [ 'mailto:', address ];
- if ( subject || body )
+
+ var linkHref,
+ email = data.email,
+ address = email.address;
+
+ switch( emailProtection )
{
- var argList = [];
- linkList.push( '?' );
- subject && argList.push( 'subject=' + subject );
- body && argList.push( 'body=' + body );
- linkList.push( argList.join( '&' ) );
+ case '' :
+ case 'encode' :
+ {
+ var subject = encodeURIComponent( email.subject || '' ),
+ body = encodeURIComponent( email.body || '' );
+
+ // Build the e-mail parameters first.
+ var argList = [];
+ subject && argList.push( 'subject=' + subject );
+ body && argList.push( 'body=' + body );
+ argList = argList.length ? '?' + argList.join( '&' ) : '';
+
+ if ( emailProtection == 'encode' )
+ {
+ linkHref = [ 'javascript:void(location.href=\'mailto:\'+',
+ protectEmailAddressAsEncodedString( address ) ];
+ // parameters are optional.
+ argList && linkHref.push( '+\'', escapeSingleQuote( argList ), '\'' );
+
+ linkHref.push( ')' );
+ }
+ else
+ linkHref = [ 'mailto:', address, argList ];
+
+ break;
+ }
+ default :
+ {
+ // Separating name and domain.
+ var nameAndDomain = address.split( '@', 2 );
+ email.name = nameAndDomain[ 0 ];
+ email.domain = nameAndDomain[ 1 ];
+
+ linkHref = [ 'javascript:', protectEmailLinkAsFunction( email ) ];
+ }
}
- attributes._cke_saved_href = linkList.join( '' );
+
+ attributes._cke_saved_href = linkHref.join( '' );
break;
- default:
}
// Popups and target.
@@ -1099,12 +1259,15 @@ CKEDITOR.dialog.add( 'link', function( editor )
addFeature( 'top' );
onclickList.push( featureList.join( ',' ), '\'); return false;' );
- attributes[ CKEDITOR.env.ie || CKEDITOR.env.webkit ? '_cke_pa_onclick' : 'onclick' ] = onclickList.join( '' );
+ attributes[ '_cke_pa_onclick' ] = onclickList.join( '' );
}
else
{
if ( data.target.type != 'notSet' && data.target.name )
attributes.target = data.target.name;
+ else
+ removeAttributes.push( 'target' );
+
removeAttributes.push( '_cke_pa_onclick', 'onclick' );
}
}
@@ -1170,7 +1333,9 @@ CKEDITOR.dialog.add( 'link', function( editor )
else
{
// We're only editing an existing link, so just overwrite the attributes.
- var element = this._.selectedElement;
+ var element = this._.selectedElement,
+ href = element.getAttribute( '_cke_saved_href' ),
+ textView = element.getHtml();
// IE BUG: Setting the name attribute to an existing link doesn't work.
// Must re-create the link from weired syntax to workaround.
@@ -1191,7 +1356,9 @@ CKEDITOR.dialog.add( 'link', function( editor )
element.setAttributes( attributes );
element.removeAttributes( removeAttributes );
-
+ // Update text view when user changes protocol #4612.
+ if (href == textView)
+ element.setHtml( attributes._cke_saved_href );
// Make the element display as an anchor if a name has been set.
if ( element.getAttribute( 'name' ) )
element.addClass( 'cke_anchor' );
@@ -1212,6 +1379,43 @@ CKEDITOR.dialog.add( 'link', function( editor )
if ( !editor.config.linkShowTargetTab )
this.hidePage( 'target' ); //Hide Target tab.
+ },
+ // Inital focus on 'url' field if link is of type URL.
+ onFocus : function()
+ {
+ var linkType = this.getContentElement( 'info', 'linkType' ),
+ urlField;
+ if ( linkType && linkType.getValue( ) == 'url' )
+ {
+ urlField = this.getContentElement( 'info', 'url' );
+ urlField.select();
+ }
}
};
-} );
+});
+
+/**
+ * The e-mail address anti-spam protection option. The protection will be
+ * applied when creating or modifying e-mail links through the editor interface.
+ * Two methods of protection can be choosed:
+ * - The e-mail parts (name, domain and any other query string) are
+ * assembled into a function call pattern. Such function must be
+ * provided by the developer in the pages that will use the contents.
+ *
- Only the e-mail address is obfuscated into a special string that
+ * has no meaning for humans or spam bots, but which is properly
+ * rendered and accepted by the browser.
+ * Both approaches require JavaScript to be enabled.
+ * @name CKEDITOR.config.emailProtection
+ * @since 3.1
+ * @type String
+ * @default '' (empty string = disabled)
+ * @example
+ * // href="mailto:tester@ckeditor.com?subject=subject&body=body"
+ * config.emailProtection = '';
+ * @example
+ * // href="e-mail"
+ * config.emailProtection = 'encode';
+ * @example
+ * // href="javascript:mt('tester','ckeditor.com','subject','body')"
+ * config.emailProtection = 'mt(NAME,DOMAIN,SUBJECT,BODY)';
+ */