source: trunk/phpgwapi/js/ckeditor/_source/plugins/link/dialogs/link.js @ 2862

Revision 2862, 38.6 KB checked in by rodsouza, 14 years ago (diff)

Ticket #663 - Atualizando e centralizando o CKEditor (v. 3.2.1)

Line 
1/*
2Copyright (c) 2003-2010, CKSource - Frederico Knabben. All rights reserved.
3For licensing, see LICENSE.html or http://ckeditor.com/license
4*/
5
6CKEDITOR.dialog.add( 'link', function( editor )
7{
8        var plugin = CKEDITOR.plugins.link;
9        // Handles the event when the "Target" selection box is changed.
10        var targetChanged = function()
11        {
12                var dialog = this.getDialog(),
13                        popupFeatures = dialog.getContentElement( 'target', 'popupFeatures' ),
14                        targetName = dialog.getContentElement( 'target', 'linkTargetName' ),
15                        value = this.getValue();
16
17                if ( !popupFeatures || !targetName )
18                        return;
19
20                popupFeatures = popupFeatures.getElement();
21                popupFeatures.hide();
22                targetName.setValue( '' );
23
24                switch ( value )
25                {
26                        case 'frame' :
27                                targetName.setLabel( editor.lang.link.targetFrameName );
28                                targetName.getElement().show();
29                                break;
30                        case 'popup' :
31                                popupFeatures.show();
32                                targetName.setLabel( editor.lang.link.targetPopupName );
33                                targetName.getElement().show();
34                                break;
35                        default :
36                                targetName.setValue( value );
37                                targetName.getElement().hide();
38                                break;
39                }
40
41        };
42
43        // Handles the event when the "Type" selection box is changed.
44        var linkTypeChanged = function()
45        {
46                var dialog = this.getDialog(),
47                        partIds = [ 'urlOptions', 'anchorOptions', 'emailOptions' ],
48                        typeValue = this.getValue(),
49                        uploadTab = dialog.definition.getContents( 'upload' ),
50                        uploadInitiallyHidden = uploadTab && uploadTab.hidden;
51
52                if ( typeValue == 'url' )
53                {
54                        if ( editor.config.linkShowTargetTab )
55                                dialog.showPage( 'target' );
56                        if ( !uploadInitiallyHidden )
57                                dialog.showPage( 'upload' );
58                }
59                else
60                {
61                        dialog.hidePage( 'target' );
62                        if ( !uploadInitiallyHidden )
63                                dialog.hidePage( 'upload' );
64                }
65
66                for ( var i = 0 ; i < partIds.length ; i++ )
67                {
68                        var element = dialog.getContentElement( 'info', partIds[i] );
69                        if ( !element )
70                                continue;
71
72                        element = element.getElement().getParent().getParent();
73                        if ( partIds[i] == typeValue + 'Options' )
74                                element.show();
75                        else
76                                element.hide();
77                }
78        };
79
80        // Loads the parameters in a selected link to the link dialog fields.
81        var javascriptProtocolRegex = /^javascript:/,
82                emailRegex = /^mailto:([^?]+)(?:\?(.+))?$/,
83                emailSubjectRegex = /subject=([^;?:@&=$,\/]*)/,
84                emailBodyRegex = /body=([^;?:@&=$,\/]*)/,
85                anchorRegex = /^#(.*)$/,
86                urlRegex = /^((?:http|https|ftp|news):\/\/)?(.*)$/,
87                selectableTargets = /^(_(?:self|top|parent|blank))$/,
88                encodedEmailLinkRegex = /^javascript:void\(location\.href='mailto:'\+String\.fromCharCode\(([^)]+)\)(?:\+'(.*)')?\)$/,
89                functionCallProtectedEmailLinkRegex = /^javascript:([^(]+)\(([^)]+)\)$/;
90
91        var popupRegex =
92                /\s*window.open\(\s*this\.href\s*,\s*(?:'([^']*)'|null)\s*,\s*'([^']*)'\s*\)\s*;\s*return\s*false;*\s*/;
93        var popupFeaturesRegex = /(?:^|,)([^=]+)=(\d+|yes|no)/gi;
94
95        var parseLink = function( editor, element )
96        {
97                var href = ( element  && ( element.getAttribute( '_cke_saved_href' ) || element.getAttribute( 'href' ) ) ) || '',
98                        javascriptMatch,
99                        emailMatch,
100                        anchorMatch,
101                        urlMatch,
102                        retval = {};
103
104                if ( ( javascriptMatch = href.match( javascriptProtocolRegex ) ) )
105                {
106                        if ( emailProtection == 'encode' )
107                        {
108                                href = href.replace( encodedEmailLinkRegex,
109                                                function ( match, protectedAddress, rest )
110                                                {
111                                                        return 'mailto:' +
112                                                               String.fromCharCode.apply( String, protectedAddress.split( ',' ) ) +
113                                                               ( rest && unescapeSingleQuote( rest ) );
114                                                });
115                        }
116                        // Protected email link as function call.
117                        else if ( emailProtection )
118                        {
119                                href.replace( functionCallProtectedEmailLinkRegex, function( match, funcName, funcArgs )
120                                {
121                                        if ( funcName == compiledProtectionFunction.name )
122                                        {
123                                                retval.type = 'email';
124                                                var email = retval.email = {};
125
126                                                var paramRegex = /[^,\s]+/g,
127                                                        paramQuoteRegex = /(^')|('$)/g,
128                                                        paramsMatch = funcArgs.match( paramRegex ),
129                                                        paramsMatchLength = paramsMatch.length,
130                                                        paramName,
131                                                        paramVal;
132
133                                                for ( var i = 0; i < paramsMatchLength; i++ )
134                                                {
135                                                        paramVal = decodeURIComponent( unescapeSingleQuote( paramsMatch[ i ].replace( paramQuoteRegex, '' ) ) );
136                                                        paramName = compiledProtectionFunction.params[ i ].toLowerCase();
137                                                        email[ paramName ] = paramVal;
138                                                }
139                                                email.address = [ email.name, email.domain ].join( '@' );
140                                        }
141                                } );
142                        }
143                }
144
145                if ( !retval.type )
146                {
147                        if ( ( anchorMatch = href.match( anchorRegex ) ) )
148                        {
149                                retval.type = 'anchor';
150                                retval.anchor = {};
151                                retval.anchor.name = retval.anchor.id = anchorMatch[1];
152                        }
153                        // Protected email link as encoded string.
154                        else if ( ( emailMatch = href.match( emailRegex ) ) )
155                        {
156                                var subjectMatch = href.match( emailSubjectRegex ),
157                                        bodyMatch = href.match( emailBodyRegex );
158
159                                retval.type = 'email';
160                                var email = ( retval.email = {} );
161                                email.address = emailMatch[ 1 ];
162                                subjectMatch && ( email.subject = decodeURIComponent( subjectMatch[ 1 ] ) );
163                                bodyMatch && ( email.body = decodeURIComponent( bodyMatch[ 1 ] ) );
164                        }
165                        // urlRegex matches empty strings, so need to check for href as well.
166                        else if (  href && ( urlMatch = href.match( urlRegex ) ) )
167                        {
168                                retval.type = 'url';
169                                retval.url = {};
170                                retval.url.protocol = urlMatch[1];
171                                retval.url.url = urlMatch[2];
172                        }
173                        else
174                                retval.type = 'url';
175                }
176
177                // Load target and popup settings.
178                if ( element )
179                {
180                        var target = element.getAttribute( 'target' );
181                        retval.target = {};
182                        retval.adv = {};
183
184                        // IE BUG: target attribute is an empty string instead of null in IE if it's not set.
185                        if ( !target )
186                        {
187                                var onclick = element.getAttribute( '_cke_pa_onclick' ) || element.getAttribute( 'onclick' ),
188                                        onclickMatch = onclick && onclick.match( popupRegex );
189                                if ( onclickMatch )
190                                {
191                                        retval.target.type = 'popup';
192                                        retval.target.name = onclickMatch[1];
193
194                                        var featureMatch;
195                                        while ( ( featureMatch = popupFeaturesRegex.exec( onclickMatch[2] ) ) )
196                                        {
197                                                if ( featureMatch[2] == 'yes' || featureMatch[2] == '1' )
198                                                        retval.target[ featureMatch[1] ] = true;
199                                                else if ( isFinite( featureMatch[2] ) )
200                                                        retval.target[ featureMatch[1] ] = featureMatch[2];
201                                        }
202                                }
203                        }
204                        else
205                        {
206                                var targetMatch = target.match( selectableTargets );
207                                if ( targetMatch )
208                                        retval.target.type = retval.target.name = target;
209                                else
210                                {
211                                        retval.target.type = 'frame';
212                                        retval.target.name = target;
213                                }
214                        }
215
216                        var me = this;
217                        var advAttr = function( inputName, attrName )
218                        {
219                                var value = element.getAttribute( attrName );
220                                if ( value !== null )
221                                        retval.adv[ inputName ] = value || '';
222                        };
223                        advAttr( 'advId', 'id' );
224                        advAttr( 'advLangDir', 'dir' );
225                        advAttr( 'advAccessKey', 'accessKey' );
226                        advAttr( 'advName', 'name' );
227                        advAttr( 'advLangCode', 'lang' );
228                        advAttr( 'advTabIndex', 'tabindex' );
229                        advAttr( 'advTitle', 'title' );
230                        advAttr( 'advContentType', 'type' );
231                        advAttr( 'advCSSClasses', 'class' );
232                        advAttr( 'advCharset', 'charset' );
233                        advAttr( 'advStyles', 'style' );
234                }
235
236                // Find out whether we have any anchors in the editor.
237                // Get all IMG elements in CK document.
238                var elements = editor.document.getElementsByTag( 'img' ),
239                        realAnchors = new CKEDITOR.dom.nodeList( editor.document.$.anchors ),
240                        anchors = retval.anchors = [];
241
242                for ( var i = 0; i < elements.count() ; i++ )
243                {
244                        var item = elements.getItem( i );
245                        if ( item.getAttribute( '_cke_realelement' ) && item.getAttribute( '_cke_real_element_type' ) == 'anchor' )
246                        {
247                                anchors.push( editor.restoreRealElement( item ) );
248                        }
249                }
250
251                for ( i = 0 ; i < realAnchors.count() ; i++ )
252                        anchors.push( realAnchors.getItem( i ) );
253
254                for ( i = 0 ; i < anchors.length ; i++ )
255                {
256                        item = anchors[ i ];
257                        anchors[ i ] = { name : item.getAttribute( 'name' ), id : item.getAttribute( 'id' ) };
258                }
259
260                // Record down the selected element in the dialog.
261                this._.selectedElement = element;
262
263                return retval;
264        };
265
266        var setupParams = function( page, data )
267        {
268                if ( data[page] )
269                        this.setValue( data[page][this.id] || '' );
270        };
271
272        var setupPopupParams = function( data )
273        {
274                return setupParams.call( this, 'target', data );
275        };
276
277        var setupAdvParams = function( data )
278        {
279                return setupParams.call( this, 'adv', data );
280        };
281
282        var commitParams = function( page, data )
283        {
284                if ( !data[page] )
285                        data[page] = {};
286
287                data[page][this.id] = this.getValue() || '';
288        };
289
290        var commitPopupParams = function( data )
291        {
292                return commitParams.call( this, 'target', data );
293        };
294
295        var commitAdvParams = function( data )
296        {
297                return commitParams.call( this, 'adv', data );
298        };
299
300        function unescapeSingleQuote( str )
301        {
302                return str.replace( /\\'/g, '\'' );
303        }
304
305        function escapeSingleQuote( str )
306        {
307                return str.replace( /'/g, '\\$&' );
308        }
309
310        var emailProtection = editor.config.emailProtection || '';
311
312        // Compile the protection function pattern.
313        if ( emailProtection && emailProtection != 'encode' )
314        {
315                var compiledProtectionFunction = {};
316
317                emailProtection.replace( /^([^(]+)\(([^)]+)\)$/, function( match, funcName, params )
318                {
319                        compiledProtectionFunction.name = funcName;
320                        compiledProtectionFunction.params = [];
321                        params.replace( /[^,\s]+/g, function( param )
322                        {
323                                compiledProtectionFunction.params.push( param );
324                        } );
325                } );
326        }
327
328        function protectEmailLinkAsFunction( email )
329        {
330                var retval,
331                        name = compiledProtectionFunction.name,
332                        params = compiledProtectionFunction.params,
333                        paramName,
334                        paramValue;
335
336                retval = [ name, '(' ];
337                for ( var i = 0; i < params.length; i++ )
338                {
339                        paramName = params[ i ].toLowerCase();
340                        paramValue = email[ paramName ];
341
342                        i > 0 && retval.push( ',' );
343                        retval.push( '\'',
344                                                 paramValue ?
345                                                 escapeSingleQuote( encodeURIComponent( email[ paramName ] ) )
346                                                 : '',
347                                                 '\'');
348                }
349                retval.push( ')' );
350                return retval.join( '' );
351        }
352
353        function protectEmailAddressAsEncodedString( address )
354        {
355                var charCode,
356                        length = address.length,
357                        encodedChars = [];
358                for ( var i = 0; i < length; i++ )
359                {
360                        charCode = address.charCodeAt( i );
361                        encodedChars.push( charCode );
362                }
363                return 'String.fromCharCode(' + encodedChars.join( ',' ) + ')';
364        }
365
366        return {
367                title : editor.lang.link.title,
368                minWidth : 350,
369                minHeight : 230,
370                contents : [
371                        {
372                                id : 'info',
373                                label : editor.lang.link.info,
374                                title : editor.lang.link.info,
375                                elements :
376                                [
377                                        {
378                                                id : 'linkType',
379                                                type : 'select',
380                                                label : editor.lang.link.type,
381                                                'default' : 'url',
382                                                items :
383                                                [
384                                                        [ editor.lang.link.toUrl, 'url' ],
385                                                        [ editor.lang.link.toAnchor, 'anchor' ],
386                                                        [ editor.lang.link.toEmail, 'email' ]
387                                                ],
388                                                onChange : linkTypeChanged,
389                                                setup : function( data )
390                                                {
391                                                        if ( data.type )
392                                                                this.setValue( data.type );
393                                                },
394                                                commit : function( data )
395                                                {
396                                                        data.type = this.getValue();
397                                                }
398                                        },
399                                        {
400                                                type : 'vbox',
401                                                id : 'urlOptions',
402                                                children :
403                                                [
404                                                        {
405                                                                type : 'hbox',
406                                                                widths : [ '25%', '75%' ],
407                                                                children :
408                                                                [
409                                                                        {
410                                                                                id : 'protocol',
411                                                                                type : 'select',
412                                                                                label : editor.lang.common.protocol,
413                                                                                'default' : 'http://',
414                                                                                style : 'width : 100%;',
415                                                                                items :
416                                                                                [
417                                                                                        [ 'http://' ],
418                                                                                        [ 'https://' ],
419                                                                                        [ 'ftp://' ],
420                                                                                        [ 'news://' ],
421                                                                                        [ editor.lang.link.other , '' ]
422                                                                                ],
423                                                                                setup : function( data )
424                                                                                {
425                                                                                        if ( data.url )
426                                                                                                this.setValue( data.url.protocol || '' );
427                                                                                },
428                                                                                commit : function( data )
429                                                                                {
430                                                                                        if ( !data.url )
431                                                                                                data.url = {};
432
433                                                                                        data.url.protocol = this.getValue();
434                                                                                }
435                                                                        },
436                                                                        {
437                                                                                type : 'text',
438                                                                                id : 'url',
439                                                                                label : editor.lang.common.url,
440                                                                                required: true,
441                                                                                onLoad : function ()
442                                                                                {
443                                                                                        this.allowOnChange = true;
444                                                                                },
445                                                                                onKeyUp : function()
446                                                                                {
447                                                                                        this.allowOnChange = false;
448                                                                                        var     protocolCmb = this.getDialog().getContentElement( 'info', 'protocol' ),
449                                                                                                url = this.getValue(),
450                                                                                                urlOnChangeProtocol = /^(http|https|ftp|news):\/\/(?=.)/gi,
451                                                                                                urlOnChangeTestOther = /^((javascript:)|[#\/\.\?])/gi;
452
453                                                                                        var protocol = urlOnChangeProtocol.exec( url );
454                                                                                        if ( protocol )
455                                                                                        {
456                                                                                                this.setValue( url.substr( protocol[ 0 ].length ) );
457                                                                                                protocolCmb.setValue( protocol[ 0 ].toLowerCase() );
458                                                                                        }
459                                                                                        else if ( urlOnChangeTestOther.test( url ) )
460                                                                                                protocolCmb.setValue( '' );
461
462                                                                                        this.allowOnChange = true;
463                                                                                },
464                                                                                onChange : function()
465                                                                                {
466                                                                                        if ( this.allowOnChange )               // Dont't call on dialog load.
467                                                                                                this.onKeyUp();
468                                                                                },
469                                                                                validate : function()
470                                                                                {
471                                                                                        var dialog = this.getDialog();
472
473                                                                                        if ( dialog.getContentElement( 'info', 'linkType' ) &&
474                                                                                                        dialog.getValueOf( 'info', 'linkType' ) != 'url' )
475                                                                                                return true;
476
477                                                                                        if ( this.getDialog().fakeObj ) // Edit Anchor.
478                                                                                                return true;
479
480                                                                                        var func = CKEDITOR.dialog.validate.notEmpty( editor.lang.link.noUrl );
481                                                                                        return func.apply( this );
482                                                                                },
483                                                                                setup : function( data )
484                                                                                {
485                                                                                        this.allowOnChange = false;
486                                                                                        if ( data.url )
487                                                                                                this.setValue( data.url.url );
488                                                                                        this.allowOnChange = true;
489
490                                                                                },
491                                                                                commit : function( data )
492                                                                                {
493                                                                                        // IE will not trigger the onChange event if the mouse has been used
494                                                                                        // to carry all the operations #4724
495                                                                                        this.onChange();
496
497                                                                                        if ( !data.url )
498                                                                                                data.url = {};
499
500                                                                                        data.url.url = this.getValue();
501                                                                                        this.allowOnChange = false;
502                                                                                }
503                                                                        }
504                                                                ],
505                                                                setup : function( data )
506                                                                {
507                                                                        if ( !this.getDialog().getContentElement( 'info', 'linkType' ) )
508                                                                                this.getElement().show();
509                                                                }
510                                                        },
511                                                        {
512                                                                type : 'button',
513                                                                id : 'browse',
514                                                                hidden : 'true',
515                                                                filebrowser : 'info:url',
516                                                                label : editor.lang.common.browseServer
517                                                        }
518                                                ]
519                                        },
520                                        {
521                                                type : 'vbox',
522                                                id : 'anchorOptions',
523                                                width : 260,
524                                                align : 'center',
525                                                padding : 0,
526                                                children :
527                                                [
528                                                        {
529                                                                type : 'fieldset',
530                                                                id : 'selectAnchorText',
531                                                                label : editor.lang.link.selectAnchor,
532                                                                setup : function( data )
533                                                                {
534                                                                        if ( data.anchors.length > 0 )
535                                                                                this.getElement().show();
536                                                                        else
537                                                                                this.getElement().hide();
538                                                                },
539                                                                children :
540                                                                [
541                                                                        {
542                                                                                type : 'hbox',
543                                                                                id : 'selectAnchor',
544                                                                                children :
545                                                                                [
546                                                                                        {
547                                                                                                type : 'select',
548                                                                                                id : 'anchorName',
549                                                                                                'default' : '',
550                                                                                                label : editor.lang.link.anchorName,
551                                                                                                style : 'width: 100%;',
552                                                                                                items :
553                                                                                                [
554                                                                                                        [ '' ]
555                                                                                                ],
556                                                                                                setup : function( data )
557                                                                                                {
558                                                                                                        this.clear();
559                                                                                                        this.add( '' );
560                                                                                                        for ( var i = 0 ; i < data.anchors.length ; i++ )
561                                                                                                        {
562                                                                                                                if ( data.anchors[i].name )
563                                                                                                                        this.add( data.anchors[i].name );
564                                                                                                        }
565
566                                                                                                        if ( data.anchor )
567                                                                                                                this.setValue( data.anchor.name );
568
569                                                                                                        var linkType = this.getDialog().getContentElement( 'info', 'linkType' );
570                                                                                                        if ( linkType && linkType.getValue() == 'email' )
571                                                                                                                this.focus();
572                                                                                                },
573                                                                                                commit : function( data )
574                                                                                                {
575                                                                                                        if ( !data.anchor )
576                                                                                                                data.anchor = {};
577
578                                                                                                        data.anchor.name = this.getValue();
579                                                                                                }
580                                                                                        },
581                                                                                        {
582                                                                                                type : 'select',
583                                                                                                id : 'anchorId',
584                                                                                                'default' : '',
585                                                                                                label : editor.lang.link.anchorId,
586                                                                                                style : 'width: 100%;',
587                                                                                                items :
588                                                                                                [
589                                                                                                        [ '' ]
590                                                                                                ],
591                                                                                                setup : function( data )
592                                                                                                {
593                                                                                                        this.clear();
594                                                                                                        this.add( '' );
595                                                                                                        for ( var i = 0 ; i < data.anchors.length ; i++ )
596                                                                                                        {
597                                                                                                                if ( data.anchors[i].id )
598                                                                                                                        this.add( data.anchors[i].id );
599                                                                                                        }
600
601                                                                                                        if ( data.anchor )
602                                                                                                                this.setValue( data.anchor.id );
603                                                                                                },
604                                                                                                commit : function( data )
605                                                                                                {
606                                                                                                        if ( !data.anchor )
607                                                                                                                data.anchor = {};
608
609                                                                                                        data.anchor.id = this.getValue();
610                                                                                                }
611                                                                                        }
612                                                                                ],
613                                                                                setup : function( data )
614                                                                                {
615                                                                                        if ( data.anchors.length > 0 )
616                                                                                                this.getElement().show();
617                                                                                        else
618                                                                                                this.getElement().hide();
619                                                                                }
620                                                                        }
621                                                                ]
622                                                        },
623                                                        {
624                                                                type : 'html',
625                                                                id : 'noAnchors',
626                                                                style : 'text-align: center;',
627                                                                html : '<div role="label" tabIndex="-1">' + CKEDITOR.tools.htmlEncode( editor.lang.link.noAnchors ) + '</div>',
628                                                                // Focus the first element defined in above html.
629                                                                focus : true,
630                                                                setup : function( data )
631                                                                {
632                                                                        if ( data.anchors.length < 1 )
633                                                                                this.getElement().show();
634                                                                        else
635                                                                                this.getElement().hide();
636                                                                }
637                                                        }
638                                                ],
639                                                setup : function( data )
640                                                {
641                                                        if ( !this.getDialog().getContentElement( 'info', 'linkType' ) )
642                                                                this.getElement().hide();
643                                                }
644                                        },
645                                        {
646                                                type :  'vbox',
647                                                id : 'emailOptions',
648                                                padding : 1,
649                                                children :
650                                                [
651                                                        {
652                                                                type : 'text',
653                                                                id : 'emailAddress',
654                                                                label : editor.lang.link.emailAddress,
655                                                                required : true,
656                                                                validate : function()
657                                                                {
658                                                                        var dialog = this.getDialog();
659
660                                                                        if ( !dialog.getContentElement( 'info', 'linkType' ) ||
661                                                                                        dialog.getValueOf( 'info', 'linkType' ) != 'email' )
662                                                                                return true;
663
664                                                                        var func = CKEDITOR.dialog.validate.notEmpty( editor.lang.link.noEmail );
665                                                                        return func.apply( this );
666                                                                },
667                                                                setup : function( data )
668                                                                {
669                                                                        if ( data.email )
670                                                                                this.setValue( data.email.address );
671
672                                                                        var linkType = this.getDialog().getContentElement( 'info', 'linkType' );
673                                                                        if ( linkType && linkType.getValue() == 'email' )
674                                                                                this.select();
675                                                                },
676                                                                commit : function( data )
677                                                                {
678                                                                        if ( !data.email )
679                                                                                data.email = {};
680
681                                                                        data.email.address = this.getValue();
682                                                                }
683                                                        },
684                                                        {
685                                                                type : 'text',
686                                                                id : 'emailSubject',
687                                                                label : editor.lang.link.emailSubject,
688                                                                setup : function( data )
689                                                                {
690                                                                        if ( data.email )
691                                                                                this.setValue( data.email.subject );
692                                                                },
693                                                                commit : function( data )
694                                                                {
695                                                                        if ( !data.email )
696                                                                                data.email = {};
697
698                                                                        data.email.subject = this.getValue();
699                                                                }
700                                                        },
701                                                        {
702                                                                type : 'textarea',
703                                                                id : 'emailBody',
704                                                                label : editor.lang.link.emailBody,
705                                                                rows : 3,
706                                                                'default' : '',
707                                                                setup : function( data )
708                                                                {
709                                                                        if ( data.email )
710                                                                                this.setValue( data.email.body );
711                                                                },
712                                                                commit : function( data )
713                                                                {
714                                                                        if ( !data.email )
715                                                                                data.email = {};
716
717                                                                        data.email.body = this.getValue();
718                                                                }
719                                                        }
720                                                ],
721                                                setup : function( data )
722                                                {
723                                                        if ( !this.getDialog().getContentElement( 'info', 'linkType' ) )
724                                                                this.getElement().hide();
725                                                }
726                                        }
727                                ]
728                        },
729                        {
730                                id : 'target',
731                                label : editor.lang.link.target,
732                                title : editor.lang.link.target,
733                                elements :
734                                [
735                                        {
736                                                type : 'hbox',
737                                                widths : [ '50%', '50%' ],
738                                                children :
739                                                [
740                                                        {
741                                                                type : 'select',
742                                                                id : 'linkTargetType',
743                                                                label : editor.lang.common.target,
744                                                                'default' : 'notSet',
745                                                                style : 'width : 100%;',
746                                                                'items' :
747                                                                [
748                                                                        [ editor.lang.common.notSet, 'notSet' ],
749                                                                        [ editor.lang.link.targetFrame, 'frame' ],
750                                                                        [ editor.lang.link.targetPopup, 'popup' ],
751                                                                        [ editor.lang.common.targetNew, '_blank' ],
752                                                                        [ editor.lang.common.targetTop, '_top' ],
753                                                                        [ editor.lang.common.targetSelf, '_self' ],
754                                                                        [ editor.lang.common.targetParent, '_parent' ]
755                                                                ],
756                                                                onChange : targetChanged,
757                                                                setup : function( data )
758                                                                {
759                                                                        if ( data.target )
760                                                                                this.setValue( data.target.type );
761                                                                },
762                                                                commit : function( data )
763                                                                {
764                                                                        if ( !data.target )
765                                                                                data.target = {};
766
767                                                                        data.target.type = this.getValue();
768                                                                }
769                                                        },
770                                                        {
771                                                                type : 'text',
772                                                                id : 'linkTargetName',
773                                                                label : editor.lang.link.targetFrameName,
774                                                                'default' : '',
775                                                                setup : function( data )
776                                                                {
777                                                                        if ( data.target )
778                                                                                this.setValue( data.target.name );
779                                                                },
780                                                                commit : function( data )
781                                                                {
782                                                                        if ( !data.target )
783                                                                                data.target = {};
784
785                                                                        data.target.name = this.getValue().replace(/\W/gi, '');
786                                                                }
787                                                        }
788                                                ]
789                                        },
790                                        {
791                                                type : 'vbox',
792                                                width : 260,
793                                                align : 'center',
794                                                padding : 2,
795                                                id : 'popupFeatures',
796                                                children :
797                                                [
798                                                        {
799                                                                type : 'fieldset',
800                                                                label : editor.lang.link.popupFeatures,
801                                                                children :
802                                                                [
803                                                                        {
804                                                                                type : 'hbox',
805                                                                                children :
806                                                                                [
807                                                                                        {
808                                                                                                type : 'checkbox',
809                                                                                                id : 'resizable',
810                                                                                                label : editor.lang.link.popupResizable,
811                                                                                                setup : setupPopupParams,
812                                                                                                commit : commitPopupParams
813                                                                                        },
814                                                                                        {
815                                                                                                type : 'checkbox',
816                                                                                                id : 'status',
817                                                                                                label : editor.lang.link.popupStatusBar,
818                                                                                                setup : setupPopupParams,
819                                                                                                commit : commitPopupParams
820
821                                                                                        }
822                                                                                ]
823                                                                        },
824                                                                        {
825                                                                                type : 'hbox',
826                                                                                children :
827                                                                                [
828                                                                                        {
829                                                                                                type : 'checkbox',
830                                                                                                id : 'location',
831                                                                                                label : editor.lang.link.popupLocationBar,
832                                                                                                setup : setupPopupParams,
833                                                                                                commit : commitPopupParams
834
835                                                                                        },
836                                                                                        {
837                                                                                                type : 'checkbox',
838                                                                                                id : 'toolbar',
839                                                                                                label : editor.lang.link.popupToolbar,
840                                                                                                setup : setupPopupParams,
841                                                                                                commit : commitPopupParams
842
843                                                                                        }
844                                                                                ]
845                                                                        },
846                                                                        {
847                                                                                type : 'hbox',
848                                                                                children :
849                                                                                [
850                                                                                        {
851                                                                                                type : 'checkbox',
852                                                                                                id : 'menubar',
853                                                                                                label : editor.lang.link.popupMenuBar,
854                                                                                                setup : setupPopupParams,
855                                                                                                commit : commitPopupParams
856
857                                                                                        },
858                                                                                        {
859                                                                                                type : 'checkbox',
860                                                                                                id : 'fullscreen',
861                                                                                                label : editor.lang.link.popupFullScreen,
862                                                                                                setup : setupPopupParams,
863                                                                                                commit : commitPopupParams
864
865                                                                                        }
866                                                                                ]
867                                                                        },
868                                                                        {
869                                                                                type : 'hbox',
870                                                                                children :
871                                                                                [
872                                                                                        {
873                                                                                                type : 'checkbox',
874                                                                                                id : 'scrollbars',
875                                                                                                label : editor.lang.link.popupScrollBars,
876                                                                                                setup : setupPopupParams,
877                                                                                                commit : commitPopupParams
878
879                                                                                        },
880                                                                                        {
881                                                                                                type : 'checkbox',
882                                                                                                id : 'dependent',
883                                                                                                label : editor.lang.link.popupDependent,
884                                                                                                setup : setupPopupParams,
885                                                                                                commit : commitPopupParams
886
887                                                                                        }
888                                                                                ]
889                                                                        },
890                                                                        {
891                                                                                type : 'hbox',
892                                                                                children :
893                                                                                [
894                                                                                        {
895                                                                                                type :  'text',
896                                                                                                widths : [ '30%', '70%' ],
897                                                                                                labelLayout : 'horizontal',
898                                                                                                label : editor.lang.link.popupWidth,
899                                                                                                id : 'width',
900                                                                                                setup : setupPopupParams,
901                                                                                                commit : commitPopupParams
902
903                                                                                        },
904                                                                                        {
905                                                                                                type :  'text',
906                                                                                                labelLayout : 'horizontal',
907                                                                                                widths : [ '55%', '45%' ],
908                                                                                                label : editor.lang.link.popupLeft,
909                                                                                                id : 'left',
910                                                                                                setup : setupPopupParams,
911                                                                                                commit : commitPopupParams
912
913                                                                                        }
914                                                                                ]
915                                                                        },
916                                                                        {
917                                                                                type : 'hbox',
918                                                                                children :
919                                                                                [
920                                                                                        {
921                                                                                                type :  'text',
922                                                                                                labelLayout : 'horizontal',
923                                                                                                widths : [ '30%', '70%' ],
924                                                                                                label : editor.lang.link.popupHeight,
925                                                                                                id : 'height',
926                                                                                                setup : setupPopupParams,
927                                                                                                commit : commitPopupParams
928
929                                                                                        },
930                                                                                        {
931                                                                                                type :  'text',
932                                                                                                labelLayout : 'horizontal',
933                                                                                                label : editor.lang.link.popupTop,
934                                                                                                widths : [ '55%', '45%' ],
935                                                                                                id : 'top',
936                                                                                                setup : setupPopupParams,
937                                                                                                commit : commitPopupParams
938
939                                                                                        }
940                                                                                ]
941                                                                        }
942                                                                ]
943                                                        }
944                                                ]
945                                        }
946                                ]
947                        },
948                        {
949                                id : 'upload',
950                                label : editor.lang.link.upload,
951                                title : editor.lang.link.upload,
952                                hidden : true,
953                                filebrowser : 'uploadButton',
954                                elements :
955                                [
956                                        {
957                                                type : 'file',
958                                                id : 'upload',
959                                                label : editor.lang.common.upload,
960                                                style: 'height:40px',
961                                                size : 29
962                                        },
963                                        {
964                                                type : 'fileButton',
965                                                id : 'uploadButton',
966                                                label : editor.lang.common.uploadSubmit,
967                                                filebrowser : 'info:url',
968                                                'for' : [ 'upload', 'upload' ]
969                                        }
970                                ]
971                        },
972                        {
973                                id : 'advanced',
974                                label : editor.lang.link.advanced,
975                                title : editor.lang.link.advanced,
976                                elements :
977                                [
978                                        {
979                                                type : 'vbox',
980                                                padding : 1,
981                                                children :
982                                                [
983                                                        {
984                                                                type : 'hbox',
985                                                                widths : [ '45%', '35%', '20%' ],
986                                                                children :
987                                                                [
988                                                                        {
989                                                                                type : 'text',
990                                                                                id : 'advId',
991                                                                                label : editor.lang.link.id,
992                                                                                setup : setupAdvParams,
993                                                                                commit : commitAdvParams
994                                                                        },
995                                                                        {
996                                                                                type : 'select',
997                                                                                id : 'advLangDir',
998                                                                                label : editor.lang.link.langDir,
999                                                                                'default' : '',
1000                                                                                style : 'width:110px',
1001                                                                                items :
1002                                                                                [
1003                                                                                        [ editor.lang.common.notSet, '' ],
1004                                                                                        [ editor.lang.link.langDirLTR, 'ltr' ],
1005                                                                                        [ editor.lang.link.langDirRTL, 'rtl' ]
1006                                                                                ],
1007                                                                                setup : setupAdvParams,
1008                                                                                commit : commitAdvParams
1009                                                                        },
1010                                                                        {
1011                                                                                type : 'text',
1012                                                                                id : 'advAccessKey',
1013                                                                                width : '80px',
1014                                                                                label : editor.lang.link.acccessKey,
1015                                                                                maxLength : 1,
1016                                                                                setup : setupAdvParams,
1017                                                                                commit : commitAdvParams
1018
1019                                                                        }
1020                                                                ]
1021                                                        },
1022                                                        {
1023                                                                type : 'hbox',
1024                                                                widths : [ '45%', '35%', '20%' ],
1025                                                                children :
1026                                                                [
1027                                                                        {
1028                                                                                type : 'text',
1029                                                                                label : editor.lang.link.name,
1030                                                                                id : 'advName',
1031                                                                                setup : setupAdvParams,
1032                                                                                commit : commitAdvParams
1033
1034                                                                        },
1035                                                                        {
1036                                                                                type : 'text',
1037                                                                                label : editor.lang.link.langCode,
1038                                                                                id : 'advLangCode',
1039                                                                                width : '110px',
1040                                                                                'default' : '',
1041                                                                                setup : setupAdvParams,
1042                                                                                commit : commitAdvParams
1043
1044                                                                        },
1045                                                                        {
1046                                                                                type : 'text',
1047                                                                                label : editor.lang.link.tabIndex,
1048                                                                                id : 'advTabIndex',
1049                                                                                width : '80px',
1050                                                                                maxLength : 5,
1051                                                                                setup : setupAdvParams,
1052                                                                                commit : commitAdvParams
1053
1054                                                                        }
1055                                                                ]
1056                                                        }
1057                                                ]
1058                                        },
1059                                        {
1060                                                type : 'vbox',
1061                                                padding : 1,
1062                                                children :
1063                                                [
1064                                                        {
1065                                                                type : 'hbox',
1066                                                                widths : [ '45%', '55%' ],
1067                                                                children :
1068                                                                [
1069                                                                        {
1070                                                                                type : 'text',
1071                                                                                label : editor.lang.link.advisoryTitle,
1072                                                                                'default' : '',
1073                                                                                id : 'advTitle',
1074                                                                                setup : setupAdvParams,
1075                                                                                commit : commitAdvParams
1076
1077                                                                        },
1078                                                                        {
1079                                                                                type : 'text',
1080                                                                                label : editor.lang.link.advisoryContentType,
1081                                                                                'default' : '',
1082                                                                                id : 'advContentType',
1083                                                                                setup : setupAdvParams,
1084                                                                                commit : commitAdvParams
1085
1086                                                                        }
1087                                                                ]
1088                                                        },
1089                                                        {
1090                                                                type : 'hbox',
1091                                                                widths : [ '45%', '55%' ],
1092                                                                children :
1093                                                                [
1094                                                                        {
1095                                                                                type : 'text',
1096                                                                                label : editor.lang.link.cssClasses,
1097                                                                                'default' : '',
1098                                                                                id : 'advCSSClasses',
1099                                                                                setup : setupAdvParams,
1100                                                                                commit : commitAdvParams
1101
1102                                                                        },
1103                                                                        {
1104                                                                                type : 'text',
1105                                                                                label : editor.lang.link.charset,
1106                                                                                'default' : '',
1107                                                                                id : 'advCharset',
1108                                                                                setup : setupAdvParams,
1109                                                                                commit : commitAdvParams
1110
1111                                                                        }
1112                                                                ]
1113                                                        },
1114                                                        {
1115                                                                type : 'hbox',
1116                                                                children :
1117                                                                [
1118                                                                        {
1119                                                                                type : 'text',
1120                                                                                label : editor.lang.link.styles,
1121                                                                                'default' : '',
1122                                                                                id : 'advStyles',
1123                                                                                setup : setupAdvParams,
1124                                                                                commit : commitAdvParams
1125
1126                                                                        }
1127                                                                ]
1128                                                        }
1129                                                ]
1130                                        }
1131                                ]
1132                        }
1133                ],
1134                onShow : function()
1135                {
1136                        this.fakeObj = false;
1137
1138                        var editor = this.getParentEditor(),
1139                                selection = editor.getSelection(),
1140                                element = null;
1141
1142                        // Fill in all the relevant fields if there's already one link selected.
1143                        if ( ( element = plugin.getSelectedLink( editor ) ) && element.hasAttribute( 'href' ) )
1144                                selection.selectElement( element );
1145                        else if ( ( element = selection.getSelectedElement() ) && element.is( 'img' )
1146                                        && element.getAttribute( '_cke_real_element_type' )
1147                                        && element.getAttribute( '_cke_real_element_type' ) == 'anchor' )
1148                        {
1149                                this.fakeObj = element;
1150                                element = editor.restoreRealElement( this.fakeObj );
1151                                selection.selectElement( this.fakeObj );
1152                        }
1153                        else
1154                                element = null;
1155
1156                        this.setupContent( parseLink.apply( this, [ editor, element ] ) );
1157                },
1158                onOk : function()
1159                {
1160                        var attributes = { href : 'javascript:void(0)/*' + CKEDITOR.tools.getNextNumber() + '*/' },
1161                                removeAttributes = [],
1162                                data = { href : attributes.href },
1163                                me = this,
1164                                editor = this.getParentEditor();
1165
1166                        this.commitContent( data );
1167
1168                        // Compose the URL.
1169                        switch ( data.type || 'url' )
1170                        {
1171                                case 'url':
1172                                        var protocol = ( data.url && data.url.protocol != undefined ) ? data.url.protocol : 'http://',
1173                                                url = ( data.url && data.url.url ) || '';
1174                                        attributes._cke_saved_href = ( url.indexOf( '/' ) === 0 ) ? url : protocol + url;
1175                                        break;
1176                                case 'anchor':
1177                                        var name = ( data.anchor && data.anchor.name ),
1178                                                id = ( data.anchor && data.anchor.id );
1179                                        attributes._cke_saved_href = '#' + ( name || id || '' );
1180                                        break;
1181                                case 'email':
1182
1183                                        var linkHref,
1184                                                email = data.email,
1185                                                address = email.address;
1186
1187                                        switch( emailProtection )
1188                                        {
1189                                                case '' :
1190                                                case 'encode' :
1191                                                {
1192                                                        var subject = encodeURIComponent( email.subject || '' ),
1193                                                                body = encodeURIComponent( email.body || '' );
1194
1195                                                        // Build the e-mail parameters first.
1196                                                        var argList = [];
1197                                                        subject && argList.push( 'subject=' + subject );
1198                                                        body && argList.push( 'body=' + body );
1199                                                        argList = argList.length ? '?' + argList.join( '&' ) : '';
1200
1201                                                        if ( emailProtection == 'encode' )
1202                                                        {
1203                                                                linkHref = [ 'javascript:void(location.href=\'mailto:\'+',
1204                                                                                         protectEmailAddressAsEncodedString( address ) ];
1205                                                                // parameters are optional.
1206                                                                argList && linkHref.push( '+\'', escapeSingleQuote( argList ), '\'' );
1207
1208                                                                linkHref.push( ')' );
1209                                                        }
1210                                                        else
1211                                                                linkHref = [ 'mailto:', address, argList ];
1212
1213                                                        break;
1214                                                }
1215                                                default :
1216                                                {
1217                                                        // Separating name and domain.
1218                                                        var nameAndDomain = address.split( '@', 2 );
1219                                                        email.name = nameAndDomain[ 0 ];
1220                                                        email.domain = nameAndDomain[ 1 ];
1221
1222                                                        linkHref = [ 'javascript:', protectEmailLinkAsFunction( email ) ];
1223                                                }
1224                                        }
1225
1226                                        attributes._cke_saved_href = linkHref.join( '' );
1227                                        break;
1228                        }
1229
1230                        // Popups and target.
1231                        if ( data.target )
1232                        {
1233                                if ( data.target.type == 'popup' )
1234                                {
1235                                        var onclickList = [ 'window.open(this.href, \'',
1236                                                        data.target.name || '', '\', \'' ];
1237                                        var featureList = [ 'resizable', 'status', 'location', 'toolbar', 'menubar', 'fullscreen',
1238                                                        'scrollbars', 'dependent' ];
1239                                        var featureLength = featureList.length;
1240                                        var addFeature = function( featureName )
1241                                        {
1242                                                if ( data.target[ featureName ] )
1243                                                        featureList.push( featureName + '=' + data.target[ featureName ] );
1244                                        };
1245
1246                                        for ( var i = 0 ; i < featureLength ; i++ )
1247                                                featureList[i] = featureList[i] + ( data.target[ featureList[i] ] ? '=yes' : '=no' ) ;
1248                                        addFeature( 'width' );
1249                                        addFeature( 'left' );
1250                                        addFeature( 'height' );
1251                                        addFeature( 'top' );
1252
1253                                        onclickList.push( featureList.join( ',' ), '\'); return false;' );
1254                                        attributes[ '_cke_pa_onclick' ] = onclickList.join( '' );
1255                                }
1256                                else
1257                                {
1258                                        if ( data.target.type != 'notSet' && data.target.name )
1259                                                attributes.target = data.target.name;
1260                                        else
1261                                                removeAttributes.push( 'target' );
1262
1263                                        removeAttributes.push( '_cke_pa_onclick', 'onclick' );
1264                                }
1265                        }
1266
1267                        // Advanced attributes.
1268                        if ( data.adv )
1269                        {
1270                                var advAttr = function( inputName, attrName )
1271                                {
1272                                        var value = data.adv[ inputName ];
1273                                        if ( value )
1274                                                attributes[attrName] = value;
1275                                        else
1276                                                removeAttributes.push( attrName );
1277                                };
1278
1279                                if ( this._.selectedElement )
1280                                        advAttr( 'advId', 'id' );
1281                                advAttr( 'advLangDir', 'dir' );
1282                                advAttr( 'advAccessKey', 'accessKey' );
1283                                advAttr( 'advName', 'name' );
1284                                advAttr( 'advLangCode', 'lang' );
1285                                advAttr( 'advTabIndex', 'tabindex' );
1286                                advAttr( 'advTitle', 'title' );
1287                                advAttr( 'advContentType', 'type' );
1288                                advAttr( 'advCSSClasses', 'class' );
1289                                advAttr( 'advCharset', 'charset' );
1290                                advAttr( 'advStyles', 'style' );
1291                        }
1292
1293                        if ( !this._.selectedElement )
1294                        {
1295                                // Create element if current selection is collapsed.
1296                                var selection = editor.getSelection(),
1297                                        ranges = selection.getRanges();
1298                                if ( ranges.length == 1 && ranges[0].collapsed )
1299                                {
1300                                        var text = new CKEDITOR.dom.text( attributes._cke_saved_href, editor.document );
1301                                        ranges[0].insertNode( text );
1302                                        ranges[0].selectNodeContents( text );
1303                                        selection.selectRanges( ranges );
1304                                }
1305
1306                                // Apply style.
1307                                var style = new CKEDITOR.style( { element : 'a', attributes : attributes } );
1308                                style.type = CKEDITOR.STYLE_INLINE;             // need to override... dunno why.
1309                                style.apply( editor.document );
1310
1311                                // Id. Apply only to the first link.
1312                                if ( data.adv && data.adv.advId )
1313                                {
1314                                        var links = this.getParentEditor().document.$.getElementsByTagName( 'a' );
1315                                        for ( i = 0 ; i < links.length ; i++ )
1316                                        {
1317                                                if ( links[i].href == attributes.href )
1318                                                {
1319                                                        links[i].id = data.adv.advId;
1320                                                        break;
1321                                                }
1322                                        }
1323                                }
1324                        }
1325                        else
1326                        {
1327                                // We're only editing an existing link, so just overwrite the attributes.
1328                                var element = this._.selectedElement,
1329                                        href = element.getAttribute( '_cke_saved_href' ),
1330                                        textView = element.getHtml();
1331
1332                                // IE BUG: Setting the name attribute to an existing link doesn't work.
1333                                // Must re-create the link from weired syntax to workaround.
1334                                if ( CKEDITOR.env.ie && attributes.name != element.getAttribute( 'name' ) )
1335                                {
1336                                        var newElement = new CKEDITOR.dom.element( '<a name="' + CKEDITOR.tools.htmlEncode( attributes.name ) + '">',
1337                                                        editor.document );
1338
1339                                        selection = editor.getSelection();
1340
1341                                        element.moveChildren( newElement );
1342                                        element.copyAttributes( newElement, { name : 1 } );
1343                                        newElement.replace( element );
1344                                        element = newElement;
1345
1346                                        selection.selectElement( element );
1347                                }
1348
1349                                element.setAttributes( attributes );
1350                                element.removeAttributes( removeAttributes );
1351                                // Update text view when user changes protocol #4612.
1352                                if (href == textView)
1353                                        element.setHtml( attributes._cke_saved_href );
1354                                // Make the element display as an anchor if a name has been set.
1355                                if ( element.getAttribute( 'name' ) )
1356                                        element.addClass( 'cke_anchor' );
1357                                else
1358                                        element.removeClass( 'cke_anchor' );
1359
1360                                if ( this.fakeObj )
1361                                        editor.createFakeElement( element, 'cke_anchor', 'anchor' ).replace( this.fakeObj );
1362
1363                                delete this._.selectedElement;
1364                        }
1365                },
1366                onLoad : function()
1367                {
1368                        if ( !editor.config.linkShowAdvancedTab )
1369                                this.hidePage( 'advanced' );            //Hide Advanded tab.
1370
1371                        if ( !editor.config.linkShowTargetTab )
1372                                this.hidePage( 'target' );              //Hide Target tab.
1373
1374                },
1375                // Inital focus on 'url' field if link is of type URL.
1376                onFocus : function()
1377                {
1378                        var linkType = this.getContentElement( 'info', 'linkType' ),
1379                                        urlField;
1380                        if ( linkType && linkType.getValue( ) == 'url' )
1381                        {
1382                                urlField = this.getContentElement( 'info', 'url' );
1383                                urlField.select();
1384                        }
1385                }
1386        };
1387});
1388
1389/**
1390 * The e-mail address anti-spam protection option. The protection will be
1391 * applied when creating or modifying e-mail links through the editor interface.<br>
1392 * Two methods of protection can be choosed:
1393 * <ol> <li>The e-mail parts (name, domain and any other query string) are
1394 *                      assembled into a function call pattern. Such function must be
1395 *                      provided by the developer in the pages that will use the contents.
1396 *              <li>Only the e-mail address is obfuscated into a special string that
1397 *                      has no meaning for humans or spam bots, but which is properly
1398 *                      rendered and accepted by the browser.</li></ol>
1399 * Both approaches require JavaScript to be enabled.
1400 * @name CKEDITOR.config.emailProtection
1401 * @since 3.1
1402 * @type String
1403 * @default '' (empty string = disabled)
1404 * @example
1405 * // href="mailto:tester@ckeditor.com?subject=subject&body=body"
1406 * config.emailProtection = '';
1407 * @example
1408 * // 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>"
1409 * config.emailProtection = 'encode';
1410 * @example
1411 * // href="javascript:mt('tester','ckeditor.com','subject','body')"
1412 * config.emailProtection = 'mt(NAME,DOMAIN,SUBJECT,BODY)';
1413 */
Note: See TracBrowser for help on using the repository browser.