PageRenderTime 63ms CodeModel.GetById 25ms app.highlight 30ms RepoModel.GetById 0ms app.codeStats 1ms

/EQT_V2/EQT/EQTWebApp/fckeditor/editor/dialog/fck_link/fck_link.js

http://sgsoft-las.googlecode.com/
JavaScript | 893 lines | 632 code | 153 blank | 108 comment | 159 complexity | d17768d5624ce956430c70711e83f00c MD5 | raw file
Possible License(s): LGPL-2.1
  1/*
  2 * FCKeditor - The text editor for Internet - http://www.fckeditor.net
  3 * Copyright (C) 2003-2009 Frederico Caldeira Knabben
  4 *
  5 * == BEGIN LICENSE ==
  6 *
  7 * Licensed under the terms of any of the following licenses at your
  8 * choice:
  9 *
 10 *  - GNU General Public License Version 2 or later (the "GPL")
 11 *    http://www.gnu.org/licenses/gpl.html
 12 *
 13 *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
 14 *    http://www.gnu.org/licenses/lgpl.html
 15 *
 16 *  - Mozilla Public License Version 1.1 or later (the "MPL")
 17 *    http://www.mozilla.org/MPL/MPL-1.1.html
 18 *
 19 * == END LICENSE ==
 20 *
 21 * Scripts related to the Link dialog window (see fck_link.html).
 22 */
 23
 24var dialog	= window.parent ;
 25var oEditor = dialog.InnerDialogLoaded() ;
 26
 27var FCK			= oEditor.FCK ;
 28var FCKLang		= oEditor.FCKLang ;
 29var FCKConfig	= oEditor.FCKConfig ;
 30var FCKRegexLib	= oEditor.FCKRegexLib ;
 31var FCKTools	= oEditor.FCKTools ;
 32
 33//#### Dialog Tabs
 34
 35// Set the dialog tabs.
 36dialog.AddTab( 'Info', FCKLang.DlgLnkInfoTab ) ;
 37
 38if ( !FCKConfig.LinkDlgHideTarget )
 39	dialog.AddTab( 'Target', FCKLang.DlgLnkTargetTab, true ) ;
 40
 41if ( FCKConfig.LinkUpload )
 42	dialog.AddTab( 'Upload', FCKLang.DlgLnkUpload, true ) ;
 43
 44if ( !FCKConfig.LinkDlgHideAdvanced )
 45	dialog.AddTab( 'Advanced', FCKLang.DlgAdvancedTag ) ;
 46
 47// Function called when a dialog tag is selected.
 48function OnDialogTabChange( tabCode )
 49{
 50	ShowE('divInfo'		, ( tabCode == 'Info' ) ) ;
 51	ShowE('divTarget'	, ( tabCode == 'Target' ) ) ;
 52	ShowE('divUpload'	, ( tabCode == 'Upload' ) ) ;
 53	ShowE('divAttribs'	, ( tabCode == 'Advanced' ) ) ;
 54
 55	dialog.SetAutoSize( true ) ;
 56}
 57
 58//#### Regular Expressions library.
 59var oRegex = new Object() ;
 60
 61oRegex.UriProtocol = /^(((http|https|ftp|news):\/\/)|mailto:)/gi ;
 62
 63oRegex.UrlOnChangeProtocol = /^(http|https|ftp|news):\/\/(?=.)/gi ;
 64
 65oRegex.UrlOnChangeTestOther = /^((javascript:)|[#\/\.])/gi ;
 66
 67oRegex.ReserveTarget = /^_(blank|self|top|parent)$/i ;
 68
 69oRegex.PopupUri = /^javascript:void\(\s*window.open\(\s*'([^']+)'\s*,\s*(?:'([^']*)'|null)\s*,\s*'([^']*)'\s*\)\s*\)\s*$/ ;
 70
 71// Accessible popups
 72oRegex.OnClickPopup = /^\s*on[cC]lick="\s*window.open\(\s*this\.href\s*,\s*(?:'([^']*)'|null)\s*,\s*'([^']*)'\s*\)\s*;\s*return\s*false;*\s*"$/ ;
 73
 74oRegex.PopupFeatures = /(?:^|,)([^=]+)=(\d+|yes|no)/gi ;
 75
 76//#### Parser Functions
 77
 78var oParser = new Object() ;
 79
 80// This method simply returns the two inputs in numerical order. You can even
 81// provide strings, as the method would parseInt() the values.
 82oParser.SortNumerical = function(a, b)
 83{
 84	return parseInt( a, 10 ) - parseInt( b, 10 ) ;
 85}
 86
 87oParser.ParseEMailParams = function(sParams)
 88{
 89	// Initialize the oEMailParams object.
 90	var oEMailParams = new Object() ;
 91	oEMailParams.Subject = '' ;
 92	oEMailParams.Body = '' ;
 93
 94	var aMatch = sParams.match( /(^|^\?|&)subject=([^&]+)/i ) ;
 95	if ( aMatch ) oEMailParams.Subject = decodeURIComponent( aMatch[2] ) ;
 96
 97	aMatch = sParams.match( /(^|^\?|&)body=([^&]+)/i ) ;
 98	if ( aMatch ) oEMailParams.Body = decodeURIComponent( aMatch[2] ) ;
 99
100	return oEMailParams ;
101}
102
103// This method returns either an object containing the email info, or FALSE
104// if the parameter is not an email link.
105oParser.ParseEMailUri = function( sUrl )
106{
107	// Initializes the EMailInfo object.
108	var oEMailInfo = new Object() ;
109	oEMailInfo.Address = '' ;
110	oEMailInfo.Subject = '' ;
111	oEMailInfo.Body = '' ;
112
113	var aLinkInfo = sUrl.match( /^(\w+):(.*)$/ ) ;
114	if ( aLinkInfo && aLinkInfo[1] == 'mailto' )
115	{
116		// This seems to be an unprotected email link.
117		var aParts = aLinkInfo[2].match( /^([^\?]+)\??(.+)?/ ) ;
118		if ( aParts )
119		{
120			// Set the e-mail address.
121			oEMailInfo.Address = aParts[1] ;
122
123			// Look for the optional e-mail parameters.
124			if ( aParts[2] )
125			{
126				var oEMailParams = oParser.ParseEMailParams( aParts[2] ) ;
127				oEMailInfo.Subject = oEMailParams.Subject ;
128				oEMailInfo.Body = oEMailParams.Body ;
129			}
130		}
131		return oEMailInfo ;
132	}
133	else if ( aLinkInfo && aLinkInfo[1] == 'javascript' )
134	{
135		// This may be a protected email.
136
137		// Try to match the url against the EMailProtectionFunction.
138		var func = FCKConfig.EMailProtectionFunction ;
139		if ( func != null )
140		{
141			try
142			{
143				// Escape special chars.
144				func = func.replace( /([\/^$*+.?()\[\]])/g, '\\$1' ) ;
145
146				// Define the possible keys.
147				var keys = new Array('NAME', 'DOMAIN', 'SUBJECT', 'BODY') ;
148
149				// Get the order of the keys (hold them in the array <pos>) and
150				// the function replaced by regular expression patterns.
151				var sFunc = func ;
152				var pos = new Array() ;
153				for ( var i = 0 ; i < keys.length ; i ++ )
154				{
155					var rexp = new RegExp( keys[i] ) ;
156					var p = func.search( rexp ) ;
157					if ( p >= 0 )
158					{
159						sFunc = sFunc.replace( rexp, '\'([^\']*)\'' ) ;
160						pos[pos.length] = p + ':' + keys[i] ;
161					}
162				}
163
164				// Sort the available keys.
165				pos.sort( oParser.SortNumerical ) ;
166
167				// Replace the excaped single quotes in the url, such they do
168				// not affect the regexp afterwards.
169				aLinkInfo[2] = aLinkInfo[2].replace( /\\'/g, '###SINGLE_QUOTE###' ) ;
170
171				// Create the regexp and execute it.
172				var rFunc = new RegExp( '^' + sFunc + '$' ) ;
173				var aMatch = rFunc.exec( aLinkInfo[2] ) ;
174				if ( aMatch )
175				{
176					var aInfo = new Array();
177					for ( var i = 1 ; i < aMatch.length ; i ++ )
178					{
179						var k = pos[i-1].match(/^\d+:(.+)$/) ;
180						aInfo[k[1]] = aMatch[i].replace(/###SINGLE_QUOTE###/g, '\'') ;
181					}
182
183					// Fill the EMailInfo object that will be returned
184					oEMailInfo.Address = aInfo['NAME'] + '@' + aInfo['DOMAIN'] ;
185					oEMailInfo.Subject = decodeURIComponent( aInfo['SUBJECT'] ) ;
186					oEMailInfo.Body = decodeURIComponent( aInfo['BODY'] ) ;
187
188					return oEMailInfo ;
189				}
190			}
191			catch (e)
192			{
193			}
194		}
195
196		// Try to match the email against the encode protection.
197		var aMatch = aLinkInfo[2].match( /^(?:void\()?location\.href='mailto:'\+(String\.fromCharCode\([\d,]+\))\+'(.*)'\)?$/ ) ;
198		if ( aMatch )
199		{
200			// The link is encoded
201			oEMailInfo.Address = eval( aMatch[1] ) ;
202			if ( aMatch[2] )
203			{
204				var oEMailParams = oParser.ParseEMailParams( aMatch[2] ) ;
205				oEMailInfo.Subject = oEMailParams.Subject ;
206				oEMailInfo.Body = oEMailParams.Body ;
207			}
208			return oEMailInfo ;
209		}
210	}
211	return false;
212}
213
214oParser.CreateEMailUri = function( address, subject, body )
215{
216	// Switch for the EMailProtection setting.
217	switch ( FCKConfig.EMailProtection )
218	{
219		case 'function' :
220			var func = FCKConfig.EMailProtectionFunction ;
221			if ( func == null )
222			{
223				if ( FCKConfig.Debug )
224				{
225					alert('EMailProtection alert!\nNo function defined. Please set "FCKConfig.EMailProtectionFunction"') ;
226				}
227				return '';
228			}
229
230			// Split the email address into name and domain parts.
231			var aAddressParts = address.split( '@', 2 ) ;
232			if ( aAddressParts[1] == undefined )
233			{
234				aAddressParts[1] = '' ;
235			}
236
237			// Replace the keys by their values (embedded in single quotes).
238			func = func.replace(/NAME/g, "'" + aAddressParts[0].replace(/'/g, '\\\'') + "'") ;
239			func = func.replace(/DOMAIN/g, "'" + aAddressParts[1].replace(/'/g, '\\\'') + "'") ;
240			func = func.replace(/SUBJECT/g, "'" + encodeURIComponent( subject ).replace(/'/g, '\\\'') + "'") ;
241			func = func.replace(/BODY/g, "'" + encodeURIComponent( body ).replace(/'/g, '\\\'') + "'") ;
242
243			return 'javascript:' + func ;
244
245		case 'encode' :
246			var aParams = [] ;
247			var aAddressCode = [] ;
248
249			if ( subject.length > 0 )
250				aParams.push( 'subject='+ encodeURIComponent( subject ) ) ;
251			if ( body.length > 0 )
252				aParams.push( 'body=' + encodeURIComponent( body ) ) ;
253			for ( var i = 0 ; i < address.length ; i++ )
254				aAddressCode.push( address.charCodeAt( i ) ) ;
255
256			return 'javascript:void(location.href=\'mailto:\'+String.fromCharCode(' + aAddressCode.join( ',' ) + ')+\'?' + aParams.join( '&' ) + '\')' ;
257	}
258
259	// EMailProtection 'none'
260
261	var sBaseUri = 'mailto:' + address ;
262
263	var sParams = '' ;
264
265	if ( subject.length > 0 )
266		sParams = '?subject=' + encodeURIComponent( subject ) ;
267
268	if ( body.length > 0 )
269	{
270		sParams += ( sParams.length == 0 ? '?' : '&' ) ;
271		sParams += 'body=' + encodeURIComponent( body ) ;
272	}
273
274	return sBaseUri + sParams ;
275}
276
277//#### Initialization Code
278
279// oLink: The actual selected link in the editor.
280var oLink = dialog.Selection.GetSelection().MoveToAncestorNode( 'A' ) ;
281if ( oLink )
282	FCK.Selection.SelectNode( oLink ) ;
283
284window.onload = function()
285{
286	// Translate the dialog box texts.
287	oEditor.FCKLanguageManager.TranslatePage(document) ;
288
289	// Fill the Anchor Names and Ids combos.
290	LoadAnchorNamesAndIds() ;
291
292	// Load the selected link information (if any).
293	LoadSelection() ;
294
295	// Update the dialog box.
296	SetLinkType( GetE('cmbLinkType').value ) ;
297
298	// Show/Hide the "Browse Server" button.
299	GetE('divBrowseServer').style.display = FCKConfig.LinkBrowser ? '' : 'none' ;
300
301	// Show the initial dialog content.
302	GetE('divInfo').style.display = '' ;
303
304	// Set the actual uploader URL.
305	if ( FCKConfig.LinkUpload )
306		GetE('frmUpload').action = FCKConfig.LinkUploadURL ;
307
308	// Set the default target (from configuration).
309	SetDefaultTarget() ;
310
311	// Activate the "OK" button.
312	dialog.SetOkButton( true ) ;
313
314	// Select the first field.
315	switch( GetE('cmbLinkType').value )
316	{
317		case 'url' :
318			SelectField( 'txtUrl' ) ;
319			break ;
320		case 'email' :
321			SelectField( 'txtEMailAddress' ) ;
322			break ;
323		case 'anchor' :
324			if ( GetE('divSelAnchor').style.display != 'none' )
325				SelectField( 'cmbAnchorName' ) ;
326			else
327				SelectField( 'cmbLinkType' ) ;
328	}
329}
330
331var bHasAnchors ;
332
333function LoadAnchorNamesAndIds()
334{
335	// Since version 2.0, the anchors are replaced in the DOM by IMGs so the user see the icon
336	// to edit them. So, we must look for that images now.
337	var aAnchors = new Array() ;
338	var i ;
339	var oImages = oEditor.FCK.EditorDocument.getElementsByTagName( 'IMG' ) ;
340	for( i = 0 ; i < oImages.length ; i++ )
341	{
342		if ( oImages[i].getAttribute('_fckanchor') )
343			aAnchors[ aAnchors.length ] = oEditor.FCK.GetRealElement( oImages[i] ) ;
344	}
345
346	// Add also real anchors
347	var oLinks = oEditor.FCK.EditorDocument.getElementsByTagName( 'A' ) ;
348	for( i = 0 ; i < oLinks.length ; i++ )
349	{
350		if ( oLinks[i].name && ( oLinks[i].name.length > 0 ) )
351			aAnchors[ aAnchors.length ] = oLinks[i] ;
352	}
353
354	var aIds = FCKTools.GetAllChildrenIds( oEditor.FCK.EditorDocument.body ) ;
355
356	bHasAnchors = ( aAnchors.length > 0 || aIds.length > 0 ) ;
357
358	for ( i = 0 ; i < aAnchors.length ; i++ )
359	{
360		var sName = aAnchors[i].name ;
361		if ( sName && sName.length > 0 )
362			FCKTools.AddSelectOption( GetE('cmbAnchorName'), sName, sName ) ;
363	}
364
365	for ( i = 0 ; i < aIds.length ; i++ )
366	{
367		FCKTools.AddSelectOption( GetE('cmbAnchorId'), aIds[i], aIds[i] ) ;
368	}
369
370	ShowE( 'divSelAnchor'	, bHasAnchors ) ;
371	ShowE( 'divNoAnchor'	, !bHasAnchors ) ;
372}
373
374function LoadSelection()
375{
376	if ( !oLink ) return ;
377
378	var sType = 'url' ;
379
380	// Get the actual Link href.
381	var sHRef = oLink.getAttribute( '_fcksavedurl' ) ;
382	if ( sHRef == null )
383		sHRef = oLink.getAttribute( 'href' , 2 ) || '' ;
384
385	// Look for a popup javascript link.
386	var oPopupMatch = oRegex.PopupUri.exec( sHRef ) ;
387	if( oPopupMatch )
388	{
389		GetE('cmbTarget').value = 'popup' ;
390		sHRef = oPopupMatch[1] ;
391		FillPopupFields( oPopupMatch[2], oPopupMatch[3] ) ;
392		SetTarget( 'popup' ) ;
393	}
394
395	// Accessible popups, the popup data is in the onclick attribute
396	if ( !oPopupMatch )
397	{
398		var onclick = oLink.getAttribute( 'onclick_fckprotectedatt' ) ;
399		if ( onclick )
400		{
401			// Decode the protected string
402			onclick = decodeURIComponent( onclick ) ;
403
404			oPopupMatch = oRegex.OnClickPopup.exec( onclick ) ;
405			if( oPopupMatch )
406			{
407				GetE( 'cmbTarget' ).value = 'popup' ;
408				FillPopupFields( oPopupMatch[1], oPopupMatch[2] ) ;
409				SetTarget( 'popup' ) ;
410			}
411		}
412	}
413
414	// Search for the protocol.
415	var sProtocol = oRegex.UriProtocol.exec( sHRef ) ;
416
417	// Search for a protected email link.
418	var oEMailInfo = oParser.ParseEMailUri( sHRef );
419
420	if ( oEMailInfo )
421	{
422		sType = 'email' ;
423
424		GetE('txtEMailAddress').value = oEMailInfo.Address ;
425		GetE('txtEMailSubject').value = oEMailInfo.Subject ;
426		GetE('txtEMailBody').value    = oEMailInfo.Body ;
427	}
428	else if ( sProtocol )
429	{
430		sProtocol = sProtocol[0].toLowerCase() ;
431		GetE('cmbLinkProtocol').value = sProtocol ;
432
433		// Remove the protocol and get the remaining URL.
434		var sUrl = sHRef.replace( oRegex.UriProtocol, '' ) ;
435		sType = 'url' ;
436		GetE('txtUrl').value = sUrl ;
437	}
438	else if ( sHRef.substr(0,1) == '#' && sHRef.length > 1 )	// It is an anchor link.
439	{
440		sType = 'anchor' ;
441		GetE('cmbAnchorName').value = GetE('cmbAnchorId').value = sHRef.substr(1) ;
442	}
443	else					// It is another type of link.
444	{
445		sType = 'url' ;
446
447		GetE('cmbLinkProtocol').value = '' ;
448		GetE('txtUrl').value = sHRef ;
449	}
450
451	if ( !oPopupMatch )
452	{
453		// Get the target.
454		var sTarget = oLink.target ;
455
456		if ( sTarget && sTarget.length > 0 )
457		{
458			if ( oRegex.ReserveTarget.test( sTarget ) )
459			{
460				sTarget = sTarget.toLowerCase() ;
461				GetE('cmbTarget').value = sTarget ;
462			}
463			else
464				GetE('cmbTarget').value = 'frame' ;
465			GetE('txtTargetFrame').value = sTarget ;
466		}
467	}
468
469	// Get Advances Attributes
470	GetE('txtAttId').value			= oLink.id ;
471	GetE('txtAttName').value		= oLink.name ;
472	GetE('cmbAttLangDir').value		= oLink.dir ;
473	GetE('txtAttLangCode').value	= oLink.lang ;
474	GetE('txtAttAccessKey').value	= oLink.accessKey ;
475	GetE('txtAttTabIndex').value	= oLink.tabIndex <= 0 ? '' : oLink.tabIndex ;
476	GetE('txtAttTitle').value		= oLink.title ;
477	GetE('txtAttContentType').value	= oLink.type ;
478	GetE('txtAttCharSet').value		= oLink.charset ;
479
480	var sClass ;
481	if ( oEditor.FCKBrowserInfo.IsIE )
482	{
483		sClass	= oLink.getAttribute('className',2) || '' ;
484		// Clean up temporary classes for internal use:
485		sClass = sClass.replace( FCKRegexLib.FCK_Class, '' ) ;
486
487		GetE('txtAttStyle').value	= oLink.style.cssText ;
488	}
489	else
490	{
491		sClass	= oLink.getAttribute('class',2) || '' ;
492		GetE('txtAttStyle').value	= oLink.getAttribute('style',2) || '' ;
493	}
494	GetE('txtAttClasses').value	= sClass ;
495
496	// Update the Link type combo.
497	GetE('cmbLinkType').value = sType ;
498}
499
500//#### Link type selection.
501function SetLinkType( linkType )
502{
503	ShowE('divLinkTypeUrl'		, (linkType == 'url') ) ;
504	ShowE('divLinkTypeAnchor'	, (linkType == 'anchor') ) ;
505	ShowE('divLinkTypeEMail'	, (linkType == 'email') ) ;
506
507	if ( !FCKConfig.LinkDlgHideTarget )
508		dialog.SetTabVisibility( 'Target'	, (linkType == 'url') ) ;
509
510	if ( FCKConfig.LinkUpload )
511		dialog.SetTabVisibility( 'Upload'	, (linkType == 'url') ) ;
512
513	if ( !FCKConfig.LinkDlgHideAdvanced )
514		dialog.SetTabVisibility( 'Advanced'	, (linkType != 'anchor' || bHasAnchors) ) ;
515
516	if ( linkType == 'email' )
517		dialog.SetAutoSize( true ) ;
518}
519
520//#### Target type selection.
521function SetTarget( targetType )
522{
523	GetE('tdTargetFrame').style.display	= ( targetType == 'popup' ? 'none' : '' ) ;
524	GetE('tdPopupName').style.display	=
525	GetE('tablePopupFeatures').style.display = ( targetType == 'popup' ? '' : 'none' ) ;
526
527	switch ( targetType )
528	{
529		case "_blank" :
530		case "_self" :
531		case "_parent" :
532		case "_top" :
533			GetE('txtTargetFrame').value = targetType ;
534			break ;
535		case "" :
536			GetE('txtTargetFrame').value = '' ;
537			break ;
538	}
539
540	if ( targetType == 'popup' )
541		dialog.SetAutoSize( true ) ;
542}
543
544//#### Called while the user types the URL.
545function OnUrlChange()
546{
547	var sUrl = GetE('txtUrl').value ;
548	var sProtocol = oRegex.UrlOnChangeProtocol.exec( sUrl ) ;
549
550	if ( sProtocol )
551	{
552		sUrl = sUrl.substr( sProtocol[0].length ) ;
553		GetE('txtUrl').value = sUrl ;
554		GetE('cmbLinkProtocol').value = sProtocol[0].toLowerCase() ;
555	}
556	else if ( oRegex.UrlOnChangeTestOther.test( sUrl ) )
557	{
558		GetE('cmbLinkProtocol').value = '' ;
559	}
560}
561
562//#### Called while the user types the target name.
563function OnTargetNameChange()
564{
565	var sFrame = GetE('txtTargetFrame').value ;
566
567	if ( sFrame.length == 0 )
568		GetE('cmbTarget').value = '' ;
569	else if ( oRegex.ReserveTarget.test( sFrame ) )
570		GetE('cmbTarget').value = sFrame.toLowerCase() ;
571	else
572		GetE('cmbTarget').value = 'frame' ;
573}
574
575// Accessible popups
576function BuildOnClickPopup()
577{
578	var sWindowName = "'" + GetE('txtPopupName').value.replace(/\W/gi, "") + "'" ;
579
580	var sFeatures = '' ;
581	var aChkFeatures = document.getElementsByName( 'chkFeature' ) ;
582	for ( var i = 0 ; i < aChkFeatures.length ; i++ )
583	{
584		if ( i > 0 ) sFeatures += ',' ;
585		sFeatures += aChkFeatures[i].value + '=' + ( aChkFeatures[i].checked ? 'yes' : 'no' ) ;
586	}
587
588	if ( GetE('txtPopupWidth').value.length > 0 )	sFeatures += ',width=' + GetE('txtPopupWidth').value ;
589	if ( GetE('txtPopupHeight').value.length > 0 )	sFeatures += ',height=' + GetE('txtPopupHeight').value ;
590	if ( GetE('txtPopupLeft').value.length > 0 )	sFeatures += ',left=' + GetE('txtPopupLeft').value ;
591	if ( GetE('txtPopupTop').value.length > 0 )		sFeatures += ',top=' + GetE('txtPopupTop').value ;
592
593	if ( sFeatures != '' )
594		sFeatures = sFeatures + ",status" ;
595
596	return ( "window.open(this.href," + sWindowName + ",'" + sFeatures + "'); return false" ) ;
597}
598
599//#### Fills all Popup related fields.
600function FillPopupFields( windowName, features )
601{
602	if ( windowName )
603		GetE('txtPopupName').value = windowName ;
604
605	var oFeatures = new Object() ;
606	var oFeaturesMatch ;
607	while( ( oFeaturesMatch = oRegex.PopupFeatures.exec( features ) ) != null )
608	{
609		var sValue = oFeaturesMatch[2] ;
610		if ( sValue == ( 'yes' || '1' ) )
611			oFeatures[ oFeaturesMatch[1] ] = true ;
612		else if ( ! isNaN( sValue ) && sValue != 0 )
613			oFeatures[ oFeaturesMatch[1] ] = sValue ;
614	}
615
616	// Update all features check boxes.
617	var aChkFeatures = document.getElementsByName('chkFeature') ;
618	for ( var i = 0 ; i < aChkFeatures.length ; i++ )
619	{
620		if ( oFeatures[ aChkFeatures[i].value ] )
621			aChkFeatures[i].checked = true ;
622	}
623
624	// Update position and size text boxes.
625	if ( oFeatures['width'] )	GetE('txtPopupWidth').value		= oFeatures['width'] ;
626	if ( oFeatures['height'] )	GetE('txtPopupHeight').value	= oFeatures['height'] ;
627	if ( oFeatures['left'] )	GetE('txtPopupLeft').value		= oFeatures['left'] ;
628	if ( oFeatures['top'] )		GetE('txtPopupTop').value		= oFeatures['top'] ;
629}
630
631//#### The OK button was hit.
632function Ok()
633{
634	var sUri, sInnerHtml ;
635	oEditor.FCKUndo.SaveUndoStep() ;
636
637	switch ( GetE('cmbLinkType').value )
638	{
639		case 'url' :
640			sUri = GetE('txtUrl').value ;
641
642			if ( sUri.length == 0 )
643			{
644				alert( FCKLang.DlnLnkMsgNoUrl ) ;
645				return false ;
646			}
647
648			sUri = GetE('cmbLinkProtocol').value + sUri ;
649
650			break ;
651
652		case 'email' :
653			sUri = GetE('txtEMailAddress').value ;
654
655			if ( sUri.length == 0 )
656			{
657				alert( FCKLang.DlnLnkMsgNoEMail ) ;
658				return false ;
659			}
660
661			sUri = oParser.CreateEMailUri(
662				sUri,
663				GetE('txtEMailSubject').value,
664				GetE('txtEMailBody').value ) ;
665			break ;
666
667		case 'anchor' :
668			var sAnchor = GetE('cmbAnchorName').value ;
669			if ( sAnchor.length == 0 ) sAnchor = GetE('cmbAnchorId').value ;
670
671			if ( sAnchor.length == 0 )
672			{
673				alert( FCKLang.DlnLnkMsgNoAnchor ) ;
674				return false ;
675			}
676
677			sUri = '#' + sAnchor ;
678			break ;
679	}
680
681	// If no link is selected, create a new one (it may result in more than one link creation - #220).
682	var aLinks = oLink ? [ oLink ] : oEditor.FCK.CreateLink( sUri, true ) ;
683
684	// If no selection, no links are created, so use the uri as the link text (by dom, 2006-05-26)
685	var aHasSelection = ( aLinks.length > 0 ) ;
686	if ( !aHasSelection )
687	{
688		sInnerHtml = sUri;
689
690		// Built a better text for empty links.
691		switch ( GetE('cmbLinkType').value )
692		{
693			// anchor: use old behavior --> return true
694			case 'anchor':
695				sInnerHtml = sInnerHtml.replace( /^#/, '' ) ;
696				break ;
697
698			// url: try to get path
699			case 'url':
700				var oLinkPathRegEx = new RegExp("//?([^?\"']+)([?].*)?$") ;
701				var asLinkPath = oLinkPathRegEx.exec( sUri ) ;
702				if (asLinkPath != null)
703					sInnerHtml = asLinkPath[1];  // use matched path
704				break ;
705
706			// mailto: try to get email address
707			case 'email':
708				sInnerHtml = GetE('txtEMailAddress').value ;
709				break ;
710		}
711
712		// Create a new (empty) anchor.
713		aLinks = [ oEditor.FCK.InsertElement( 'a' ) ] ;
714	}
715
716	for ( var i = 0 ; i < aLinks.length ; i++ )
717	{
718		oLink = aLinks[i] ;
719
720		if ( aHasSelection )
721			sInnerHtml = oLink.innerHTML ;		// Save the innerHTML (IE changes it if it is like an URL).
722
723		oLink.href = sUri ;
724		SetAttribute( oLink, '_fcksavedurl', sUri ) ;
725
726		var onclick;
727		// Accessible popups
728		if( GetE('cmbTarget').value == 'popup' )
729		{
730			onclick = BuildOnClickPopup() ;
731			// Encode the attribute
732			onclick = encodeURIComponent( " onclick=\"" + onclick + "\"" )  ;
733			SetAttribute( oLink, 'onclick_fckprotectedatt', onclick ) ;
734		}
735		else
736		{
737			// Check if the previous onclick was for a popup:
738			// In that case remove the onclick handler.
739			onclick = oLink.getAttribute( 'onclick_fckprotectedatt' ) ;
740			if ( onclick )
741			{
742				// Decode the protected string
743				onclick = decodeURIComponent( onclick ) ;
744
745				if( oRegex.OnClickPopup.test( onclick ) )
746					SetAttribute( oLink, 'onclick_fckprotectedatt', '' ) ;
747			}
748		}
749
750		oLink.innerHTML = sInnerHtml ;		// Set (or restore) the innerHTML
751
752		// Target
753		if( GetE('cmbTarget').value != 'popup' )
754			SetAttribute( oLink, 'target', GetE('txtTargetFrame').value ) ;
755		else
756			SetAttribute( oLink, 'target', null ) ;
757
758		// Let's set the "id" only for the first link to avoid duplication.
759		if ( i == 0 )
760			SetAttribute( oLink, 'id', GetE('txtAttId').value ) ;
761
762		// Advances Attributes
763		SetAttribute( oLink, 'name'		, GetE('txtAttName').value ) ;
764		SetAttribute( oLink, 'dir'		, GetE('cmbAttLangDir').value ) ;
765		SetAttribute( oLink, 'lang'		, GetE('txtAttLangCode').value ) ;
766		SetAttribute( oLink, 'accesskey', GetE('txtAttAccessKey').value ) ;
767		SetAttribute( oLink, 'tabindex'	, ( GetE('txtAttTabIndex').value > 0 ? GetE('txtAttTabIndex').value : null ) ) ;
768		SetAttribute( oLink, 'title'	, GetE('txtAttTitle').value ) ;
769		SetAttribute( oLink, 'type'		, GetE('txtAttContentType').value ) ;
770		SetAttribute( oLink, 'charset'	, GetE('txtAttCharSet').value ) ;
771
772		if ( oEditor.FCKBrowserInfo.IsIE )
773		{
774			var sClass = GetE('txtAttClasses').value ;
775			// If it's also an anchor add an internal class
776			if ( GetE('txtAttName').value.length != 0 )
777				sClass += ' FCK__AnchorC' ;
778			SetAttribute( oLink, 'className', sClass ) ;
779
780			oLink.style.cssText = GetE('txtAttStyle').value ;
781		}
782		else
783		{
784			SetAttribute( oLink, 'class', GetE('txtAttClasses').value ) ;
785			SetAttribute( oLink, 'style', GetE('txtAttStyle').value ) ;
786		}
787	}
788
789	// Select the (first) link.
790	oEditor.FCKSelection.SelectNode( aLinks[0] );
791
792	return true ;
793}
794
795function BrowseServer()
796{
797	OpenFileBrowser( FCKConfig.LinkBrowserURL, FCKConfig.LinkBrowserWindowWidth, FCKConfig.LinkBrowserWindowHeight ) ;
798}
799
800function SetUrl( url )
801{
802	GetE('txtUrl').value = url ;
803	OnUrlChange() ;
804	dialog.SetSelectedTab( 'Info' ) ;
805}
806
807function OnUploadCompleted( errorNumber, fileUrl, fileName, customMsg )
808{
809	// Remove animation
810	window.parent.Throbber.Hide() ;
811	GetE( 'divUpload' ).style.display  = '' ;
812
813	switch ( errorNumber )
814	{
815		case 0 :	// No errors
816			alert( 'Your file has been successfully uploaded' ) ;
817			break ;
818		case 1 :	// Custom error
819			alert( customMsg ) ;
820			return ;
821		case 101 :	// Custom warning
822			alert( customMsg ) ;
823			break ;
824		case 201 :
825			alert( 'A file with the same name is already available. The uploaded file has been renamed to "' + fileName + '"' ) ;
826			break ;
827		case 202 :
828			alert( 'Invalid file type' ) ;
829			return ;
830		case 203 :
831			alert( "Security error. You probably don't have enough permissions to upload. Please check your server." ) ;
832			return ;
833		case 500 :
834			alert( 'The connector is disabled' ) ;
835			break ;
836		default :
837			alert( 'Error on file upload. Error number: ' + errorNumber ) ;
838			return ;
839	}
840
841	SetUrl( fileUrl ) ;
842	GetE('frmUpload').reset() ;
843}
844
845var oUploadAllowedExtRegex	= new RegExp( FCKConfig.LinkUploadAllowedExtensions, 'i' ) ;
846var oUploadDeniedExtRegex	= new RegExp( FCKConfig.LinkUploadDeniedExtensions, 'i' ) ;
847
848function CheckUpload()
849{
850	var sFile = GetE('txtUploadFile').value ;
851
852	if ( sFile.length == 0 )
853	{
854		alert( 'Please select a file to upload' ) ;
855		return false ;
856	}
857
858	if ( ( FCKConfig.LinkUploadAllowedExtensions.length > 0 && !oUploadAllowedExtRegex.test( sFile ) ) ||
859		( FCKConfig.LinkUploadDeniedExtensions.length > 0 && oUploadDeniedExtRegex.test( sFile ) ) )
860	{
861		OnUploadCompleted( 202 ) ;
862		return false ;
863	}
864
865	// Show animation
866	window.parent.Throbber.Show( 100 ) ;
867	GetE( 'divUpload' ).style.display  = 'none' ;
868
869	return true ;
870}
871
872function SetDefaultTarget()
873{
874	var target = FCKConfig.DefaultLinkTarget || '' ;
875
876	if ( oLink || target.length == 0 )
877		return ;
878
879	switch ( target )
880	{
881		case '_blank' :
882		case '_self' :
883		case '_parent' :
884		case '_top' :
885			GetE('cmbTarget').value = target ;
886			break ;
887		default :
888			GetE('cmbTarget').value = 'frame' ;
889			break ;
890	}
891
892	GetE('txtTargetFrame').value = target ;
893}