1/*
2    Copyright (c) 2003-2012, CKSource - Frederico Knabben. All rights reserved.
3For licensing, see LICENSE.html or http://ckeditor.com/license
4*/
5oDokuWiki_FCKEditorInstanceInLinkDialog = true;
6var update_ckgeditInternalLink, update_ckgeditMediaLink;
7var fckgInternalInputId, fckgMediaInputId,ckgeditIwikiIndex,ckgeditIwikiData;
8var ck_m_files_protocol, ckg_dialog, linkOpt;
9 window.onbeforeunload = function() { };
10
11CKEDITOR.dialog.add( 'link', function( editor )
12{
13    oDokuWiki_FCKEditorInstance.Lang = editor.lang;
14    ck_m_files_protocol =  oDokuWiki_FCKEditorInstance.mfiles ?	[ 'm-files://\u200E', 'm-files://' ] : "";
15    var Doku_Base = oDokuWiki_FCKEditorInstance.dwiki_doku_base;
16	var plugin = CKEDITOR.plugins.link;
17    var oRegex = new Object() ;
18    oRegex.doku_base = new RegExp('^' + Doku_Base.replace(/\//g,'\\/'),'g');
19    oRegex.media_internal = /lib\/exe\/fetch\.php\/(.*)/;
20    oRegex.media_rewrite_1 = /^_media\/(.*)/;
21    oRegex.media_rewrite_1Doku_Base = new RegExp('^' + Doku_Base + '_media\/(.*)');
22    oRegex.media_rewrite_2=/exe\/fetch.php\?media=(.*)/;
23    oRegex.internal_link = /doku.php\?id=(.*)/;
24    oRegex.internal_link_rewrite_2 = /doku.php\/(.*)/;
25    oRegex.internal_link_rewrite_1 = new RegExp('^' + Doku_Base + '(?!_media)(.*)');
26    oRegex.samba =/file:\/\/\/\/\/(.*)/;
27    oRegex.interwiki = /^(.*?)oIWIKIo(.*?)cIWIKIc/;
28	oRegex.samba_unsaved =/^\\\\\w+(\\\w.*)/;
29    ckg_dialog = CKEDITOR.dialog;
30	 var fckgSMBInputId;
31     var defaultFBLang = {
32        InternalLink: "internal link",
33        LinkText: "<span style='font-weight:bold'>Link Display Text</span><br />User defined Text (takes precedence over Page Name or  ID)",
34        InternalMedia: "internal media",
35        LinkPageOrId: 'Page Name creates default Dokuwiki Link: <code>[[namespace:page|]]</code><br />ID creates: <code>[[namespace:page|namespace:page]]</code>',
36        MediaFileLink: "link to media file",
37        SMBLabel: "Samba Share",
38        GetHeadingsLabel: 'Get Headings'	,
39        QStringLabel: 'Query String (For example: value_1=1&value_2=2) ',
40        ResetQS: 'Reset Query String',
41        NotSetOption: 'Not Set',
42        AdvancedInfo: "To create anchors from Dokuwiki headers, click on the Get Headings button, select the header, click OK. You can go back, select a new page and get new headers.",
43        AdvancedTabPrompt: 'Use the advanced tab to create page anchors and query strings',
44        SMBExample: "Enter your share as: \\\\Server\\directory\\file",
45        InterWikiLink: "Interwiki Link",
46        InterWikiType: "Interwiki Type",
47        InterwikiPlaceHolder: "Interwiki Replacement Text",
48        InterwikiInfo: "<div style='min-width:350px; white-space: pre-wrap;border:1px solid #cccccc; margin:auto; overflow:auto; padding:4px;line-height:125%;'>Dokuwiki\'s " +
49        "interwiki links are short-cuts which look like this: <span style='font-weight:600'>[[wp&gt;Shakespeare]]</span>, which will create a link to the English Wikipedia article on Shakespeare.  " +
50        "The <span style='font-weight:600'>wp</span> part designates a link pattern;  " +
51        "the text following the '<span style='font-weight:900'>&gt;</span>' will be inserted into the link, replacing  a place holder, which is enclosed in curly brackets, "  +
52        "as in <span style='font-weight:600'>{NAME}</span>. When there is no place holder, the replacement text will be appended to the end of the link.</div>",
53        MediaFileLink: "link to media file",
54        URLText:"<span style='font-weight:bold'>URL Display Text (optional, defaults to url)</span>",
55        LinkDispText: "Link display text (optional)",
56     };
57     var fck_Lang = editor.lang.fbrowser ? editor.lang.fbrowser : defaultFBLang;
58
59    var  translateItem = function (js_code) {
60      if(fck_Lang[js_code] && fck_Lang[js_code] != "") {
61            return fck_Lang[js_code];
62      }
63      return defaultFBLang[js_code];
64    } ;
65    ckgeditIwikiData = editor.config.ckgeditIwikiData;
66
67    var getInternalHeaders = function() {
68
69	  var dialog = this.getDialog();
70      var select_id = dialog.getContentElement('advanced', 'internalAnchor').getInputElement().$.id;
71      var select =document.getElementById(select_id);
72      var wiki_id = dialog.getContentElement('info', 'internal').getInputElement().$.id;
73      wiki_id = document.getElementById(wiki_id).value;
74      if(!wiki_id) return;
75
76      var anchorOption = {
77        push: function(title, value) {
78           this.stack[this.Index] = (new Option(title,value,false,false));
79           this.Index++;
80        },
81        Index: 0,
82        stack: undefined,
83        selection: "",
84        ini: function(title) {
85          this.stack = select.options;
86          this.stack.length = 0;
87          this.Index = 0;
88          this.push(title,'');
89        }
90    };
91
92        var params="dw_id=" +wiki_id;
93        editor.config.jquery.post(
94                editor.config.ckedit_path + "get_headers.php",
95                params,
96                function (data,status) {
97                    if(status=="success") {
98                         var str = decodeURIComponent(data);
99                         if(str.match(/^\s*__EMPTY__\s*$/)) {
100                                anchorOption.ini('No Headers Found');
101                                anchorOption.selection = "";
102                                return;
103                         }
104                           anchorOption.ini('Headings Menu');
105                           var pairs = str.split('@@');
106                            for (var i in pairs) {
107                                  var elems = pairs[i].split(/;;/);
108                                  anchorOption.push(elems[0],elems[1]);
109                             }
110                        }
111                    },
112                'html'
113            );
114	};
115
116    var openInternalLinkBrowser = function() {
117        doku_linkwiz.init(jQuery('#dw__editform'), editor);
118        doku_linkwiz.val = 'global';
119        doku_linkwiz.toggle();
120    }
121
122    var useHeading = function(wiki_id) {
123        return jQuery.ajax({
124             method: "POST",
125             url: DOKU_BASE + 'lib/exe/ajax.php',
126             data: {
127             dw_id: encodeURIComponent(wiki_id),
128             call: call="use_heads"
129             },
130           async: true,
131            dataType: "html",
132              })
133              .fail(function(jqXHR, textStatus, errorThrown )
134              {
135                alert('Error: ' + textStatus +'/' + errorThrown);
136
137              });
138};
139
140
141  var getSMBInput = function ()   {  return fckgSMBInputId; };
142  var ckg_iwikiClass;
143	// Handles the event when the "Type" selection box is changed.
144	var linkTypeChanged = function()
145	{
146
147      oDokuWiki_FCKEditorInstance.isLocalDwikiBrowser = false;
148      oDokuWiki_FCKEditorInstance.isUrlExtern = false;
149      oDokuWiki_FCKEditorInstance.isDwikiMediaFile = false;
150		var dialog = this.getDialog(),
151			partIds = [ 'urlOptions', 'anchorOptions', 'emailOptions','internalOptions','mediaOptions','sambaOptions','interwikiOptions' ],
152			typeValue = this.getValue(),
153			uploadTab = dialog.definition.getContents( 'upload' ),
154			uploadInitiallyHidden = uploadTab && uploadTab.hidden;
155
156         dialog.hidePage( 'advanced' );		//Hide Advanded tab.
157         if(typeValue == 'internal') {
158            oDokuWiki_FCKEditorInstance.isLocalDwikiBrowser = true;
159           dialog.showPage('advanced');
160         }
161         else if(typeValue == 'media') {
162            oDokuWiki_FCKEditorInstance.isDwikiMediaFile = true;
163         }
164
165		if ( typeValue == 'url' )
166		{
167            oDokuWiki_FCKEditorInstance.isUrlExtern = true;
168
169			if ( !uploadInitiallyHidden )
170				dialog.showPage( 'upload' );
171		}
172		else
173		{
174			//dialog.hidePage( 'target' );
175			if ( !uploadInitiallyHidden )
176				dialog.hidePage( 'upload' );
177		}
178
179
180		for ( var i = 0 ; i < partIds.length ; i++ )
181		{
182			var element = dialog.getContentElement( 'info', partIds[i] );
183			if ( !element )
184				continue;
185
186			element = element.getElement().getParent().getParent();
187			if ( partIds[i] == typeValue + 'Options' )
188				element.show();
189			else
190				element.hide();
191		}
192
193		dialog.layout();
194
195       };
196
197	// Loads the parameters in a selected link to the link dialog fields.
198
199	var javascriptProtocolRegex = /^javascript:/,
200		emailRegex = /^mailto:([^?]+)(?:\?(.+))?$/,
201		emailSubjectRegex = /subject=([^;?:@&=$,\/]*)/,
202		emailBodyRegex = /body=([^;?:@&=$,\/]*)/,
203		anchorRegex = /^#(.*)$/,
204		urlRegex = /^((?:http|https|ftp|news|m-files):\/\/)?(.*)$/,
205		selectableTargets = /^(_(?:self|top|parent|blank))$/,
206		encodedEmailLinkRegex = /^javascript:void\(location\.href='mailto:'\+String\.fromCharCode\(([^)]+)\)(?:\+'(.*)')?\)$/,
207		functionCallProtectedEmailLinkRegex = /^javascript:([^(]+)\(([^)]+)\)$/;
208    var intlink = Doku_Base.replace('/','\/')+'doku.php\?id=(.*)$';
209    var internalLinkRegex =  intlink + '/';
210
211
212	var popupRegex =
213		/\s*window.open\(\s*this\.href\s*,\s*(?:'([^']*)'|null)\s*,\s*'([^']*)'\s*\)\s*;\s*return\s*false;*\s*/;
214	var popupFeaturesRegex = /(?:^|,)([^=]+)=(\d+|yes|no)/gi;
215
216	var parseLink = function( editor, element )
217	{
218		var href = ( element  && ( element.data( 'cke-saved-href' ) || element.getAttribute( 'href' ) ) ) || '',
219		 	javascriptMatch,
220			emailMatch,
221			anchorMatch,
222			urlMatch,
223			retval = {};
224
225		if ( ( javascriptMatch = href.match( javascriptProtocolRegex ) ) )
226		{
227			if ( emailProtection == 'encode' )
228			{
229				href = href.replace( encodedEmailLinkRegex,
230						function ( match, protectedAddress, rest )
231						{
232							return 'mailto:' +
233							       String.fromCharCode.apply( String, protectedAddress.split( ',' ) ) +
234							       ( rest && unescapeSingleQuote( rest ) );
235						});
236			}
237			// Protected email link as function call.
238			else if ( emailProtection )
239			{
240				href.replace( functionCallProtectedEmailLinkRegex, function( match, funcName, funcArgs )
241				{
242					if ( funcName == compiledProtectionFunction.name )
243					{
244						retval.type = 'email';
245						var email = retval.email = {};
246
247						var paramRegex = /[^,\s]+/g,
248							paramQuoteRegex = /(^')|('$)/g,
249							paramsMatch = funcArgs.match( paramRegex ),
250							paramsMatchLength = paramsMatch.length,
251							paramName,
252							paramVal;
253
254						for ( var i = 0; i < paramsMatchLength; i++ )
255						{
256							paramVal = decodeURIComponent( unescapeSingleQuote( paramsMatch[ i ].replace( paramQuoteRegex, '' ) ) );
257							paramName = compiledProtectionFunction.params[ i ].toLowerCase();
258							email[ paramName ] = paramVal;
259						}
260						email.address = [ email.name, email.domain ].join( '@' );
261					}
262				} );
263			}
264		}
265
266		if ( !retval.type )
267		{
268            var class_name =  element ? element.getAttribute( 'class' )  : "";
269			if ( ( anchorMatch = href.match( anchorRegex ) ) )
270			{
271				retval.type = 'anchor';
272				retval.anchor = {};
273				retval.anchor.name = retval.anchor.id = anchorMatch[1];
274			}
275			// Protected email link as encoded string.
276			else if ( ( emailMatch = href.match( emailRegex ) ) )
277			{
278				var subjectMatch = href.match( emailSubjectRegex ),
279					bodyMatch = href.match( emailBodyRegex );
280
281				retval.type = 'email';
282				var email = ( retval.email = {} );
283				email.address = emailMatch[ 1 ];
284				subjectMatch && ( email.subject = decodeURIComponent( subjectMatch[ 1 ] ) );
285				bodyMatch && ( email.body = decodeURIComponent( bodyMatch[ 1 ] ) );
286			}
287           else if((urlMatch = href.match(oRegex.media_internal)) || (urlMatch = href.match(oRegex.media_rewrite_1))
288              || (urlMatch = href.match(oRegex.media_rewrite_2)) || (urlMatch = href.match(oRegex.media_rewrite_1Doku_Base))) {
289                    retval.type = 'media';
290                  	retval.url = {};
291				    retval.url.protocol =  "";
292					retval.url.url = "";
293					retval.url.selected =urlMatch[1];
294              }
295            else if( (urlMatch = href.match( oRegex.internal_link )) || (urlMatch = href.match( internalLinkRegex )) || ( urlMatch = href.match(oRegex.internal_link_rewrite_2))
296                        || (urlMatch = href.match( oRegex.internal_link_rewrite_1 ))
297                     )
298            {
299                    retval.type = 'internal';
300                    retval.url = {};
301                    var els = urlMatch[1].split('=');
302
303
304					retval.url.selected = els[0];
305				    retval.url.protocol = "";
306				    retval.url.url = "";
307                }
308		    else if(urlMatch = href.match(oRegex.samba)) {
309			     retval.type = 'samba';
310				 retval.url = {};
311				 retval.url.url = "";
312				 retval.url.protocol = '';
313				 retval.url.selected = '\\\\'+ urlMatch[1].replace(/\//g,"\\");
314
315			}
316			else if(urlMatch = href.match(oRegex.samba_unsaved)) {
317			    retval.type = 'samba';
318				retval.url = {};
319				retval.url.url = "";
320				retval.url.protocol = '';
321			    retval.url.selected = urlMatch[0];
322			}
323			else if( urlMatch = href.match(oRegex.interwiki) || class_name.match(/interwiki/) ) {
324                var str = "";
325                if(urlMatch && urlMatch[2]) {
326                   str =  decodeURIComponent(urlMatch[2]);
327                }
328
329              	retval.url = {};
330                ckg_iwikiClass = element.getAttribute( 'class' );  // save for interwiki
331                 var  iw_select = ckg_dialog.getContentElement("info", 'iwiki_shortcut');
332
333                 var tmp = iw_select.getInputElement().$.id;
334                 var select =document.getElementById(tmp);
335                 var match = ckg_iwikiClass.match(/iw_([^\s]+)/);
336                  if(match && match[1]) {
337                    var index = match[1].replace(/_/,'.');
338                  }
339                if(index) {
340                 if(!str) {
341                    var iwpattern = ckgeditIwikiData[index];
342                    iwpattern = iwpattern.replace(/\{\w+\}$/,"");
343                    var regex = new RegExp(iwpattern + '\(.*\)');
344                    match =  href.match(regex);
345                    str = match[1];
346                 }
347                 index = ckgeditIwikiIndex[index];
348                }
349                 if(index) {
350                   select.selectedIndex = index;
351                 }
352                 else select.selectedIndex = '0';
353                editor.config.selectedIwikiIndex = index;
354                iw_select.disable();
355                retval.type = 'interwiki';
356                retval.url.selected =str;
357                retval.url.url = str;
358
359            }
360
361			// urlRegex matches empty strings, so need to check for href as well.
362			else if (  href && ( urlMatch = href.match( urlRegex ) ) )
363			{
364                retval.type = 'url';
365				retval.url = {};
366				retval.url.protocol = urlMatch[1];
367				retval.url.url = urlMatch[2];
368			}
369			else
370				retval.type = 'url';
371		}
372
373		// Load target and popup settings.
374		if ( element )
375		{
376			var target = element.getAttribute( 'target' );
377			retval.target = {};
378			retval.adv = {};
379			var me = this;
380		}
381
382		// Record down the selected element in the dialog.
383		this._.selectedElement = element;
384		return retval;
385        };
386
387     var  insertInternalLinkText = function (text)
388       {
389           if(!text) return;
390           document.getElementById(fckgInternalInputId).disabled = true;
391           document.getElementById(fckgInternalInputId).style.fontWeight="bold" ;
392           document.getElementById(fckgInternalInputId).style.backgroundColor="#DDDDDD" ;
393           var ar = text.split(/;;/);
394           text = ar[0];
395           var title = ar[1];
396           text = text.replace(/^[\/\:]/,"");
397           text =  text.replace(/\//g,':');
398           text = ':' + text;
399           document.getElementById(fckgInternalInputId).value = text;
400           var dialog = CKEDITOR.dialog.getCurrent();
401
402        if(title && oDokuWiki_FCKEditorInstance.useheading == 'y') {
403          dialog.getContentElement("info", "internal_text").setValue(title);
404        }
405        };
406
407    update_ckgeditInternalLink = insertInternalLinkText;
408
409      var  insertMediaLinkText = function (text)
410       {
411           if(!text) return;
412           text = text.replace(/^[\/\:]/,"");
413           text =  text.replace(/\//g,':');
414           text = ':' + text;
415           document.getElementById(fckgMediaInputId).value = text;
416        };
417
418     update_ckgeditMediaLink  =  insertMediaLinkText;
419
420     var fckg_display_obj = function(obj) {
421
422
423        for(i in obj) {
424         msg = i + "=" + obj[i];
425         if(!confirm(msg))break;
426       }
427     };
428
429	var setupParams = function( page, data )
430	{
431		if ( data[page] )
432			this.setValue( data[page][this.id] || '' );
433	};
434
435	var setupPopupParams = function( data )
436	{
437		return setupParams.call( this, 'target', data );
438	};
439
440	var setupAdvParams = function( data )
441	{
442		return setupParams.call( this, 'adv', data );
443	};
444
445	var commitParams = function( page, data )
446	{
447		if ( !data[page] )
448			data[page] = {};
449
450		data[page][this.id] = this.getValue() || '';
451	};
452
453	var commitPopupParams = function( data )
454	{
455		return commitParams.call( this, 'target', data );
456	};
457
458	var commitAdvParams = function( data )
459	{
460		return commitParams.call( this, 'adv', data );
461	};
462
463	function unescapeSingleQuote( str )
464	{
465		return str.replace( /\\'/g, '\'' );
466	}
467
468	function escapeSingleQuote( str )
469	{
470		return str.replace( /'/g, '\\$&' );
471	}
472
473	var emailProtection = editor.config.emailProtection || '';
474
475	// Compile the protection function pattern.
476	if ( emailProtection && emailProtection != 'encode' )
477	{
478		var compiledProtectionFunction = {};
479
480		emailProtection.replace( /^([^(]+)\(([^)]+)\)$/, function( match, funcName, params )
481		{
482			compiledProtectionFunction.name = funcName;
483			compiledProtectionFunction.params = [];
484			params.replace( /[^,\s]+/g, function( param )
485			{
486				compiledProtectionFunction.params.push( param );
487			} );
488		} );
489	}
490
491	function protectEmailLinkAsFunction( email )
492	{
493		var retval,
494			name = compiledProtectionFunction.name,
495			params = compiledProtectionFunction.params,
496			paramName,
497			paramValue;
498
499		retval = [ name, '(' ];
500		for ( var i = 0; i < params.length; i++ )
501		{
502			paramName = params[ i ].toLowerCase();
503			paramValue = email[ paramName ];
504
505			i > 0 && retval.push( ',' );
506			retval.push( '\'',
507						 paramValue ?
508						 escapeSingleQuote( encodeURIComponent( email[ paramName ] ) )
509						 : '',
510						 '\'');
511		}
512		retval.push( ')' );
513		return retval.join( '' );
514	}
515
516	function protectEmailAddressAsEncodedString( address )
517	{
518		var charCode,
519			length = address.length,
520			encodedChars = [];
521		for ( var i = 0; i < length; i++ )
522		{
523			charCode = address.charCodeAt( i );
524			encodedChars.push( charCode );
525		}
526		return 'String.fromCharCode(' + encodedChars.join( ',' ) + ')';
527	}
528
529	function getLinkClass( ele )
530	{
531		var className = ele.getAttribute( 'class' );
532		return className ? className.replace( /\s*(?:cke_anchor_empty|cke_anchor)(?:\s*$)?/g, '' ) : '';
533	}
534
535	var commonLang = editor.lang.common,
536		linkLang = editor.lang.link;
537
538    //get link browser
539    linkOpt = {};
540    var fbUrl = CKEDITOR.instances.wiki__text.config.filebrowserBrowseUrl;
541    if (fbUrl.indexOf('fckeditor') === -1) {
542        linkOpt = {
543            type : 'button',
544			id : 'browse1',
545			label : commonLang.browseServer,
546            onClick: openInternalLinkBrowser
547        };
548    } else {
549        linkOpt = {
550            type : 'button',
551			id : 'browse1',
552			label : commonLang.browseServer,
553            filebrowser: 'info:url'
554        };
555    }
556
557	return {
558		title : linkLang.title,
559		minWidth :  475, //350,
560		minHeight : 300, //230,
561		contents : [
562			{
563				id : 'info',
564				label : linkLang.info,
565				title : linkLang.info,
566				elements :
567				[
568					{
569						id : 'linkType',
570						type : 'select',
571						label : linkLang.type,
572						'default' : 'url',
573						items :
574						[
575							[ linkLang.toUrl, 'url' ],
576                            [ translateItem('InternalLink'), 'internal' ],
577                            [translateItem('InternalMedia'), 'media' ],
578						    [ linkLang.toEmail, 'email' ],
579					        [translateItem('SMBLabel'), 'samba' ]	,
580                            [translateItem('InterWikiLink'), 'interwiki' ]
581						],
582						onChange : linkTypeChanged,
583						setup : function( data )
584						{
585							if ( data.type )
586								this.setValue( data.type );
587						},
588						commit : function( data )
589						{
590							data.type = this.getValue();
591
592						}
593					},
594
595					{
596						type : 'vbox',
597						id : 'urlOptions',
598						children :
599						[
600							{
601								type : 'hbox',
602								widths : [ '25%', '75%' ],
603								children :
604								[
605									{
606										id : 'protocol',
607										type : 'select',
608										label : commonLang.protocol,
609										'default' : 'http://',
610										items :
611										[
612											[ 'http://\u200E', 'http://' ],
613											[ 'https://\u200E', 'https://' ],
614											[ 'ftp://\u200E', 'ftp://' ],
615											[ 'news://\u200E', 'news://' ],
616                                            ck_m_files_protocol
617										],
618										setup : function( data )
619										{
620											if ( data.url )
621												this.setValue( data.url.protocol || '' );
622										},
623										commit : function( data )
624										{
625											if ( !data.url )
626												data.url = {};
627
628											data.url.protocol = this.getValue();
629										}
630									},
631									{
632										type : 'text',
633										id : 'url',
634										label : commonLang.url,
635										required: true,
636										onLoad : function ()
637										{
638											this.allowOnChange = true;
639										},
640										onKeyUp : function()
641										{
642											this.allowOnChange = false;
643											var	protocolCmb = this.getDialog().getContentElement( 'info', 'protocol' ),
644												url = this.getValue(),
645                                                urlOnChangeProtocol = /^(http|https|ftp|news|m-files):\/\/(?=.)/i,
646												urlOnChangeTestOther = /^((javascript:)|[#\/\.\?])/i;
647
648											var protocol = urlOnChangeProtocol.exec( url );
649											if ( protocol )
650											{
651												this.setValue( url.substr( protocol[ 0 ].length ) );
652												protocolCmb.setValue( protocol[ 0 ].toLowerCase() );
653											}
654											else if ( urlOnChangeTestOther.test( url ) )
655												protocolCmb.setValue( '' );
656
657											this.allowOnChange = true;
658										},
659										onChange : function()
660										{
661											if ( this.allowOnChange )		// Dont't call on dialog load.
662												this.onKeyUp();
663										},
664										validate : function()
665										{
666											var dialog = this.getDialog();
667
668											if ( dialog.getContentElement( 'info', 'linkType' ) &&
669													dialog.getValueOf( 'info', 'linkType' ) != 'url' )
670												return true;
671
672											if ( this.getDialog().fakeObj )	// Edit Anchor.
673												return true;
674
675											var func = CKEDITOR.dialog.validate.notEmpty( linkLang.noUrl );
676											return func.apply( this );
677										},
678										setup : function( data )
679										{
680											this.allowOnChange = false;
681											if ( data.url )
682												this.setValue( data.url.url );
683											this.allowOnChange = true;
684
685										},
686										commit : function( data )
687										{
688											// IE will not trigger the onChange event if the mouse has been used
689											// to carry all the operations #4724
690											this.onChange();
691
692											if ( !data.url )
693												data.url = {};
694
695											data.url.url = this.getValue();
696											this.allowOnChange = false;
697										}
698									}
699
700								],
701								setup : function( data )
702								{
703									if ( !this.getDialog().getContentElement( 'info', 'linkType' ) )
704										this.getElement().show();
705								}
706							},
707                            {
708                                type : 'text',
709                                id : 'url_text',
710                                label : translateItem('URLText'),
711                                required: false,
712                            },
713						]
714
715					},
716
717					{
718						type : 'vbox',
719                        id : 'internalOptions',
720						children :
721						[
722							linkOpt,
723                            {
724										type : 'text',
725										id : 'internal',
726										label : translateItem('InternalLink'), //"internal link",
727										required: true,
728                                        setup : function( data )
729                                        {
730                                           if(data) {
731                                            if (data.url &&  data.url.selected ) {
732                                                   var id = data.url.selected.replace(/^\:/,"");
733                                                   this.setValue(':'+ id );
734                                            }
735                                           }
736                                        },
737                            },
738                            {
739
740								type : 'text',
741								id : 'internal_text',
742								label : translateItem('LinkText'),
743								required: false,
744                            },
745                           {
746                                type: 'radio',
747                                id: 'ilinkstyle',
748                                 label: translateItem('LinkPageOrId'),
749                                items: [ [ 'Page Name', 'page' ], [ 'ID', 'id' ] ],
750                                'default': 'page',
751                                required: false
752                            },
753                            {
754                                id: 'anchorsmsg',
755                                type: 'html',
756                                html: translateItem('AdvancedTabPrompt'), //'Use the advanced tab to create page anchors and query strings',
757                             }
758						]
759					},
760
761                   {
762						type : 'vbox',
763                        id : 'interwikiOptions',
764						children :
765						[
766                            {
767										type : 'text',
768										id : 'interwiki',
769										label : translateItem('InterwikiPlaceHolder'), //"interwiki link",
770										required: true,
771                                        setup : function( data )
772                                        {
773                                           if(data) {
774                                            if (data.url &&  data.url.selected ) {
775                                                   var id = data.url.selected.replace(/^\:/,"");
776                                                   this.setValue(id );
777                                            }
778                                           }
779                                        },
780										commit : function( data )
781										{
782											if ( !data.url )
783												data.url = {};
784											data.url.selection = this.getValue();
785										},
786                            },
787                           {
788										id : 'iwiki_shortcut',
789										type : 'select',
790										label : translateItem('InterWikiType'),
791										'default' : '',
792										items :
793                                       [
794                                            [ 'Not Set', 'Not-Set' ],
795                                        ]  ,
796
797										setup : function( data )
798										{
799											if ( data.url )
800												this.setValue( data.url.iwiki_shortcut || '' );
801										},
802										commit : function( data )
803										{
804											if ( !data.url )
805												data.url = {};
806											data.url.iwiki_shortcut = this.getValue();
807										},
808                             } ,
809                            {
810                                id: 'iwikimsg',
811                                type: 'html',
812                                html:  translateItem('InterwikiInfo'),
813                             } ,
814                             {
815                               id: 'iwikidisp',
816                               type: 'text',
817                               label: translateItem('LinkDispText'),
818							   required: false,
819                             },
820
821
822						]
823					},
824
825                    {
826						type : 'vbox',
827                        id : 'mediaOptions',
828						children :
829						[
830							{
831								type : 'button',
832								id : 'browse2',
833								filebrowser : 'info:media',
834								label : commonLang.browseServer
835							},
836                            {
837										type : 'text',
838										id : 'media',
839                                        //width: '24em',
840										label :  translateItem('MediaFileLink'), //"link to media file",
841										required: true,
842                                        setup : function( data )
843                                        {
844                                           if(data) {
845                                            if (data.url &&  data.url.selected ) {
846                                                   var id = data.url.selected.replace(/^\:/,"");
847                                                   this.setValue(':'+ id );
848                                            }
849                                           }
850                                        },
851                            },
852						]
853					},
854					{
855						type : 'vbox',
856                        id : 'sambaOptions',
857						children :
858						[
859						    {
860										type: 'html',
861										id: 'smb_msg',
862										html: translateItem('SMBExample'),	//"Enter your share as: \\\\Server\\directory\\file",
863							},
864                            {
865										type : 'text',
866										id : 'samba',
867                                        width: '50',
868										label :  translateItem('SMBLabel'), //"Samba Share",
869										required: true,
870                                        setup : function( data )
871                                        {
872                                            if (data.url && data.url.selected) {
873                                                   this.setValue(data.url.selected);
874                                            }
875                                        },
876                            },
877						]
878					},
879
880					{
881						type :  'vbox',
882						id : 'emailOptions',
883						padding : 1,
884						children :
885						[
886							{
887								type : 'text',
888								id : 'emailAddress',
889								label : linkLang.emailAddress,
890								required : true,
891								validate : function()
892								{
893									var dialog = this.getDialog();
894
895									if ( !dialog.getContentElement( 'info', 'linkType' ) ||
896											dialog.getValueOf( 'info', 'linkType' ) != 'email' )
897										return true;
898
899									var func = CKEDITOR.dialog.validate.notEmpty( linkLang.noEmail );
900									return func.apply( this );
901								},
902								setup : function( data )
903								{
904									if ( data.email )
905										this.setValue( data.email.address );
906
907									var linkType = this.getDialog().getContentElement( 'info', 'linkType' );
908									if ( linkType && linkType.getValue() == 'email' )
909										this.select();
910								},
911								commit : function( data )
912								{
913									if ( !data.email )
914										data.email = {};
915
916									data.email.address = this.getValue();
917								}
918							},
919							{
920								type : 'text',
921								id : 'emailSubject',
922								label : linkLang.emailSubject,
923								setup : function( data )
924								{
925									if ( data.email )
926										this.setValue( data.email.subject );
927								},
928								commit : function( data )
929								{
930									if ( !data.email )
931										data.email = {};
932
933									data.email.subject = this.getValue();
934								}
935							},
936							{
937								type : 'textarea',
938								id : 'emailBody',
939								label : linkLang.emailBody,
940								rows : 3,
941								'default' : '',
942								setup : function( data )
943								{
944									if ( data.email )
945										this.setValue( data.email.body );
946								},
947								commit : function( data )
948								{
949									if ( !data.email )
950										data.email = {};
951
952									data.email.body = this.getValue();
953								}
954							}
955						],
956						setup : function( data )
957						{
958							if ( !this.getDialog().getContentElement( 'info', 'linkType' ) )
959								this.getElement().hide();
960						}
961					}
962				]
963			},
964
965			{
966				id : 'upload',
967				label : linkLang.upload,
968				title : linkLang.upload,
969				hidden : true,
970				filebrowser : 'uploadButton',
971				elements :
972				[
973					{
974						type : 'file',
975						id : 'upload',
976						label : commonLang.upload,
977						style: 'height:40px',
978						size : 29
979					},
980					{
981						type : 'fileButton',
982						id : 'uploadButton',
983						label : commonLang.uploadSubmit,
984						filebrowser : 'info:url',
985						'for' : [ 'upload', 'upload' ]
986					}
987				]
988			},
989			{
990				id : 'advanced',
991				label : linkLang.advanced,
992				title : linkLang.advanced,
993				elements :
994				[
995				    {
996					    id : 'msg',
997						type: 'html',
998						html: "<p style='max-width:350px; white-space: pre-wrap;'>" +
999                        translateItem('AdvancedInfo')  +"</p>"
1000					},
1001					{
1002						id : 'internalAnchor',
1003						type : 'select',
1004						'default' : '',
1005						items :
1006						[
1007							['Not Set' , '' ],
1008						],
1009						setup : function( data )
1010						{
1011							if ( data.hash )
1012								this.setValue( data.hash );
1013						},
1014						commit : function( data )
1015						{
1016							data.hash = this.getValue();
1017						}
1018					},
1019                   {
1020                    type : 'button',
1021                    id : 'getheaders',
1022                    onClick:  getInternalHeaders,
1023                    label : translateItem('GetHeadingsLabel'), //'Get Headings'
1024                  },
1025                   {
1026                    type: 'html',
1027                    html: "<br />",
1028                   },
1029                   {
1030                    type : 'text',
1031                    id : 'queryString',
1032                    label : translateItem('QStringLabel'), //'Query String (For example: value_1=1&value_2=2) ',
1033                    setup : function( data )
1034                    {
1035                        if ( data.qstring )
1036                            this.setValue( data.qstring );
1037                    },
1038                    commit : function( data )
1039                    {
1040                        data.qstring = this.getValue();
1041                    }
1042                  },
1043                   {
1044                    type : 'button',
1045                    id : 'clearquerystring',
1046                    onClick:  function() {
1047                        var dialog = this.getDialog();
1048                        var qs_id = dialog.getContentElement('advanced', 'queryString').getInputElement().$.id;
1049                        var qs = document.getElementById(qs_id);
1050                        qs.value = "";
1051                    },
1052                    label : translateItem('ResetQS'), //'Reset Query String'
1053                  },
1054					{
1055						type : 'vbox',
1056						padding : 1,
1057						hidden: true,
1058						children :
1059						[
1060
1061							{
1062								type : 'hbox',
1063								widths : [ '45%', '55%' ],
1064								children :
1065								[
1066									{
1067										type : 'text',
1068										label : linkLang.cssClasses,
1069										'default' : '',
1070										id : 'advCSSClasses',
1071										setup : setupAdvParams,
1072										commit : commitAdvParams
1073
1074									},
1075									{
1076										type : 'text',
1077										label : linkLang.charset,
1078										'default' : '',
1079										id : 'advCharset',
1080										setup : setupAdvParams,
1081										commit : commitAdvParams
1082
1083									}
1084								]
1085							},
1086						]
1087					}
1088				]
1089			}
1090		],
1091		onShow : function()
1092		{
1093			var editor = this.getParentEditor(),
1094				selection = editor.getSelection(),
1095				element = null;
1096			// Fill in all the relevant fields if there's already one link selected.
1097			if ( ( element = plugin.getSelectedLink( editor ) ) && element.hasAttribute( 'href' ) )
1098				selection.selectElement( element );
1099			else
1100				element = null;
1101
1102			this.setupContent( parseLink.apply( this, [ editor, element ] ) );
1103		},
1104
1105		onOk : function()
1106		{
1107			    var internal_text = false;
1108                var iwiki_text = false;
1109                url_text = false;
1110				var ImagesAllowed = new RegExp( oDokuWiki_FCKEditorInstance.imageUploadAllowedExtensions);
1111				var attributes = {},
1112					removeAttributes = [],
1113					linkstyle = 'page',
1114					me = this,
1115					tested  = false,
1116                    data = {},
1117					editor = this.getParentEditor();
1118
1119
1120				 var other_media = false;
1121                 var media_text;
1122
1123                 this.commitContent( data );
1124
1125				// Compose the URL.
1126			   var other_mime_file = "";
1127				switch ( data.type || 'url' )
1128				{
1129					case 'media':
1130						if(document.getElementById(fckgMediaInputId).value) {
1131							data.url.url =  document.getElementById(fckgMediaInputId).value;
1132						}
1133						data.adv.advTitle = data.url.url;
1134                        media_text = data.adv.advTitle;
1135						var mf = data.url.url.match(/(\.(\w+))$/);
1136						 other_mime_file = data.url.url.replace(/^:/,"");
1137						data.url.url=top.dokuBase + 'doku.php?id=' + data.url.url;
1138
1139						if( mf[1].match(ImagesAllowed)) {
1140							data.adv['advContentType'] = 'linkonly';
1141					   }
1142					   else {
1143							data.adv['advContentType'] = "other_mime";
1144						   data.url.url=top.dokuBase + 'lib/exe/fetch.php?media=' +  other_mime_file;
1145							 other_media = true;
1146					   }
1147					   data.adv[ 'advCSSClasses'] ="media mediafile";
1148						if(mf) data.adv[ 'advCSSClasses'] += " mf_" + mf[2];
1149						var protocol = ( data.url && data.url.protocol != undefined ) ? data.url.protocol : 'http://',
1150							url = ( data.url && CKEDITOR.tools.trim( data.url.url ) ) || '';
1151						attributes[ 'data-cke-saved-href' ] = ( url.indexOf( '/' ) === 0 ) ? url : protocol + url;
1152					break;
1153
1154					case 'internal':
1155						internal_text =  this.getValueOf( 'info', 'internal_text' );
1156						 ilinkstyle =this.getValueOf( 'info', 'ilinkstyle' );
1157                         if(!data.url.url) {
1158                            data.url.url=document.getElementById(fckgInternalInputId).value;
1159                            if(!data.url.url.match(/^:\w+/)) {
1160                                var ns = top.getCurrentWikiNS() + ':';
1161                                ns = ns.replace(/:$/,"");
1162                                var regex = new RegExp(':?'+ ns+':');
1163                                if(!data.url.url.match(regex)) {
1164                                    data.url.url = ns +':' + data.url.url;
1165                                    data.url.url = data.url.url.replace(/\:{2,}/g,':');
1166                                }
1167                            }
1168                         }
1169
1170                        if(!data.url.url.match(/\w/)) {
1171                            data.url.url = "";
1172                            internal_text = "";
1173                            break;
1174                        }
1175                        var ar = data.url.url.split(/;;/);
1176                        if(oDokuWiki_FCKEditorInstance.useheading == 'y') {
1177                            data.adv.advTitle = ar[1];
1178                        }
1179                        data.url.url = ar[0];
1180
1181                        data.url.url =  data.url.url.replace(/^.*?\/pages\//,"");
1182                        data.url.url = data.url.url.replace(/^\:/,"");
1183                        data.url.url =  ':' + data.url.url.replace(/\//g,':');
1184                        data.adv.advCSSClasses = "wikilink1";
1185
1186					   if(ilinkstyle == 'page' && oDokuWiki_FCKEditorInstance.useheading == 'n') {
1187							  var elms = data.url.url.split(':');
1188							  data.adv.advTitle = elms.pop();
1189						}
1190						else   { //if(!tested) {
1191                           data.url.url = data.url.url.replace(/^:/,"");
1192						 data.adv.advTitle = data.url.url;
1193						 }
1194						 data.url.url=top.dokuBase + 'doku.php?id=' + data.url.url;
1195						 if(data.hash) { data.url.url += '#' +data.hash;  }
1196						 if(data.qstring) { data.url.url += '&' +data.qstring;  }
1197						var protocol = ( data.url && data.url.protocol != undefined ) ? data.url.protocol : 'http://',
1198							url = ( data.url && CKEDITOR.tools.trim( data.url.url ) ) || '';
1199						attributes[ 'data-cke-saved-href' ] = ( url.indexOf( '/' ) === 0 ) ? url : protocol + url;
1200						 break;
1201
1202					case 'interwiki':
1203                        if(typeof editor.config.selectedIwikiIndex == "number") {
1204                            var id = this.getContentElement('info',  'iwiki_shortcut').getInputElement().$.id;
1205                            var select = document.getElementById(id);
1206                            select.selectedIndex = editor.config.selectedIwikiIndex;
1207                        }
1208
1209						if( ckg_iwikiClass) {
1210						   data.adv.advCSSClasses = ckg_iwikiClass;
1211						 }
1212						 else data.adv.advCSSClasses = 'interwiki ' + 'iw_' + data.url.iwiki_shortcut;
1213					    var iwiki_pattern = ckgeditIwikiData[data.url.iwiki_shortcut];
1214						data.adv.advTitle = data.url.selection;
1215						if(data.url.selection) data.url.selection = 'oIWIKIo'+data.url.selection+'cIWIKIc';
1216                        if(iwiki_pattern) {
1217                            if(iwiki_pattern.match(/\{.*?\}/) ){
1218                               data.url.url = ckgeditIwikiData[data.url.iwiki_shortcut].replace(/{.*?}/,data.url.selection);
1219                            }
1220                           else data.url.url = iwiki_pattern + data.url.selection;
1221                        }
1222
1223                       iwiki_text = this.getValueOf('info', 'iwikidisp') || "";//data.url.url;
1224					   attributes[ 'data-cke-saved-href' ] =  data.url.url;
1225
1226					  break;
1227					case 'url':
1228						var protocol = ( data.url && data.url.protocol != undefined ) ? data.url.protocol : 'http://',
1229						url = ( data.url && CKEDITOR.tools.trim( data.url.url ) ) || '';
1230					    attributes[ 'data-cke-saved-href' ] = ( url.indexOf( '/' ) === 0 ) ? url : protocol + url;
1231                        url_text =  this.getValueOf( 'info', 'url_text' );
1232						break;
1233					case 'anchor':
1234						var name = ( data.anchor && data.anchor.name ),
1235						  id = ( data.anchor && data.anchor.id );
1236						attributes[ 'data-cke-saved-href' ] = '#' + ( name || id || '' );
1237						break;
1238					 case 'samba':
1239					   if(!data.url.url) {
1240						  data.url.url=document.getElementById(getSMBInput()).value;
1241					   }
1242						if(!data.url.url) {
1243							  alert("Missing Samba Url");
1244							  return false;
1245						}
1246						data.url.protocol = "";
1247						var protocol = "";    // ( data.url && data.url.protocol != undefined ) ? data.url.protocol : '',
1248						url = ( data.url && CKEDITOR.tools.trim( data.url.url ) ) || '';
1249						attributes[ 'data-cke-saved-href' ] = ( url.indexOf( '/' ) === 0 ) ? url : protocol + url;
1250						data.adv.advCSSClasses = "windows";
1251						data.adv.advTitle = data.url.url;
1252					break;
1253					case 'email':
1254
1255						var linkHref,
1256							email = data.email,
1257							address = email.address;
1258
1259						switch( emailProtection )
1260						{
1261							case '' :
1262							case 'encode' :
1263							{
1264								var subject = encodeURIComponent( email.subject || '' ),
1265									body = encodeURIComponent( email.body || '' );
1266
1267								// Build the e-mail parameters first.
1268								var argList = [];
1269								body && argList.push( 'body=' + body );
1270								subject && argList.push( 'subject=' + subject );
1271
1272								argList = argList.length ? '?' + argList.join( '&' ) : '';
1273
1274								if ( emailProtection == 'encode' )
1275								{
1276									linkHref = [ 'javascript:void(location.href=\'mailto:\'+',
1277												 protectEmailAddressAsEncodedString( address ) ];
1278									// parameters are optional.
1279									argList && linkHref.push( '+\'', escapeSingleQuote( argList ), '\'' );
1280
1281									linkHref.push( ')' );
1282								}
1283								else
1284									linkHref = [ 'mailto:', address, argList ];
1285
1286								break;
1287							}
1288							default :
1289							{
1290								// Separating name and domain.
1291								var nameAndDomain = address.split( '@', 2 );
1292								email.name = nameAndDomain[ 0 ];
1293								email.domain = nameAndDomain[ 1 ];
1294
1295								linkHref = [ 'javascript:', protectEmailLinkAsFunction( email ) ];
1296							}
1297						}
1298
1299						attributes[ 'data-cke-saved-href' ] = linkHref.join( '' );
1300
1301						break;
1302				}
1303
1304
1305				// Advanced attributes.
1306				if ( data.adv )
1307				{
1308					var advAttr = function( inputName, attrName )
1309					{
1310						var value = data.adv[ inputName ];
1311						if ( value )
1312							attributes[attrName] = value;
1313						else
1314							removeAttributes.push( attrName );
1315					};
1316
1317					advAttr( 'advId', 'id' );
1318					advAttr( 'advLangDir', 'dir' );
1319					advAttr( 'advAccessKey', 'accessKey' );
1320
1321					if ( data.adv[ 'advName' ] )
1322						attributes[ 'name' ] = attributes[ 'data-cke-saved-name' ] = data.adv[ 'advName' ];
1323					else
1324						removeAttributes = removeAttributes.concat( [ 'data-cke-saved-name', 'name' ] );
1325
1326					advAttr( 'advLangCode', 'lang' );
1327					advAttr( 'advTabIndex', 'tabindex' );
1328					if(!other_media) {
1329						advAttr( 'advTitle', 'title' );
1330					}
1331					advAttr( 'advContentType', 'type' );
1332					advAttr( 'advCSSClasses', 'class' );
1333					advAttr( 'advCharset', 'charset' );
1334					advAttr( 'advStyles', 'style' );
1335					advAttr( 'advRel', 'rel' );
1336				}
1337
1338				var selection = editor.getSelection();
1339				var hasSelectedText = selection.getSelectedText() ? selection.getSelectedText() : false;
1340
1341				// Browser need the "href" fro copy/paste link to work. (#6641)
1342				attributes.href = attributes[ 'data-cke-saved-href' ];
1343
1344				if ( !this._.selectedElement )
1345				{
1346
1347					// Create element if current selection is collapsed.
1348
1349					var ranges = selection.getRanges( true );
1350					if ( ranges.length == 1 && ranges[0].collapsed )
1351					{
1352
1353						// Short mailto link text view (#5736).
1354
1355						var text = new CKEDITOR.dom.text( data.type == 'email' ?
1356								data.email.address : attributes[ 'data-cke-saved-href' ], editor.document );
1357
1358						ranges[0].insertNode( text );
1359						ranges[0].selectNodeContents( text );
1360						selection.selectRanges( ranges );
1361
1362					}
1363
1364				 if(navigator.userAgent.match(/(Trident|MSIE)/)  || !text) {
1365						var el = editor.document.createElement( 'a' );
1366						el.setAttribute( 'href',  attributes['href']);
1367						if(!hasSelectedText &&  (data.type == 'media' || data.type == 'internal')) {
1368						   if(internal_text) {
1369							el.setHtml(internal_text);
1370						   }
1371							else el.setHtml(data.adv.advTitle);
1372						}
1373						else el.setHtml(selection.getSelectedText());
1374						for(attr in attributes) {
1375							 if(attr.match(/href/i))continue;
1376							 el.setAttribute( attr,  attributes[attr]);
1377						}
1378						editor.insertElement( el );
1379					}
1380					else {  // Apply style.
1381						var style = new CKEDITOR.style( { element : 'a', attributes : attributes } );
1382						style.type = CKEDITOR.STYLE_INLINE;		// need to override... dunno why.
1383						style.apply( editor.document );
1384					}
1385				}
1386				else
1387				{
1388
1389					// We're only editing an existing link, so just overwrite the attributes.
1390					var element = this._.selectedElement,
1391						href = element.data( 'cke-saved-href' ),
1392						textView = element.getHtml();
1393					 if(other_media) {
1394						 attributes['type'] = 'other_mime';
1395						 attributes['title'] = ':' + other_mime_file;
1396					 }
1397					element.setAttributes( attributes );
1398					element.removeAttributes( removeAttributes );
1399
1400					if ( data.adv && data.adv.advName && CKEDITOR.plugins.link.synAnchorSelector )
1401						element.addClass( element.getChildCount() ? 'cke_anchor' : 'cke_anchor_empty' );
1402
1403					// Update text view when user changes protocol (#4612).
1404					if ( href == textView || data.type == 'email' && textView.indexOf( '@' ) != -1 )
1405					{
1406						// Short mailto link text view (#5736).
1407						element.setHtml( data.type == 'email' ?
1408							data.email.address : attributes[ 'data-cke-saved-href' ] );
1409					}
1410
1411                    if(internal_text){
1412                        element.setText(internal_text);
1413                    }
1414                    else if(iwiki_text && iwiki_text != data.adv.advTitle) {
1415                      var url =   href.replace(iwiki_text, data.adv.advTitle);
1416                      element.setText(url);
1417                    }
1418
1419					selection.selectElement( element );
1420					delete this._.selectedElement;
1421				}
1422
1423           if(text) {
1424              try {
1425              if(media_text) {
1426                   text.setText(media_text);
1427               }
1428			   else if(internal_text) {
1429               	   text.setText(internal_text);
1430			   }
1431              else if(text && iwiki_text) {
1432                   text.setText(iwiki_text);
1433               }
1434               else if(url_text) {
1435                    text.setText(url_text);
1436               }
1437				else if(text && data.adv.advTitle) {
1438					  text.setText(data.adv.advTitle);
1439				}
1440               }catch(err) {
1441                //alert(err.toString());
1442            } }
1443
1444            },
1445
1446		onLoad : function()
1447		{
1448            ckgeditIwikiData = editor.config.ckgeditIwikiData;
1449
1450            ckg_iwi_Select_Id_x = this.getContentElement('info',  'iwiki_shortcut').getInputElement().$.id;
1451            var setUpIwikiSel = function() {
1452               if(!ckgeditIwikiData) return;
1453               var select =document.getElementById(ckg_iwi_Select_Id_x);
1454               this.stack = select.options;
1455               this.stack.length = 0;
1456               this.stack[0] = (new Option("Not Set","not-set",false,false));
1457               ckgeditIwikiIndex = new Array();
1458               var count = 1;
1459               for(var i in ckgeditIwikiData) {
1460                  this.stack[count] =  new Option(i + ' >> ' + ckgeditIwikiData[i],i,false,false);
1461                  ckgeditIwikiIndex[i] = count;
1462                  count++;
1463              }
1464         };
1465         setUpIwikiSel();
1466
1467        var myStopFunction = function () {
1468                 clearInterval(myVar);
1469            }
1470
1471        oDokuWiki_FCKEditorInstance.isDwikiImage = false;
1472        fckgInternalInputId = this.getContentElement('info', 'internal').getInputElement().$.id;
1473        fckgMediaInputId = this.getContentElement('info', 'media').getInputElement().$.id;
1474        fckgSMBInputId = this.getContentElement('info', 'samba').getInputElement().$.id;
1475       // this.getContentElement("info", 'iwiki_shortcut'). disable();  //restricts attempts to enter filenames into text box
1476
1477        var update_schemes = function(proto_ref, ed) {
1478            var selectx = document.getElementById(proto_ref);
1479            var schemes = ed.config.ckgProtocols;
1480            var ar = schemes.split(/\n/);
1481            var ar_final = new Array();
1482            for(i=0;i<ar.length;i++) {
1483                if(!ar[i].match(/\w/)) continue;
1484                if(ar[i].match(/\#|http|https|ftp|news|m-files/)) {
1485                continue;
1486                }
1487                    var option = document.createElement("option");
1488                    option.value = ar[i];
1489                    option.text = ar[i] + '://\u200E';
1490                    selectx.add(option)
1491                    ar_final.push(ar[i]);
1492                }
1493        }
1494
1495      // var proto_ref = this.getContentElement('info', 'protocol').getInputElement().$.id
1496      // update_schemes(proto_ref, editor);
1497
1498       this.getContentElement('info', 'media').disable();
1499       this.hidePage( 'advanced' );		//Hide Advanded tab.
1500       this.showPage('info');
1501       ckg_dialog = this;
1502       var tab = this._.tabs[ 'advanced' ] && this._.tabs[ 'advanced' ][ 0 ];
1503       var dialog = this;
1504       var notSet = translateItem('NotSetOption');
1505       tab.on('focus', function(evt) {
1506           var select_id = dialog.getContentElement('advanced', 'internalAnchor').getInputElement().$.id;
1507           var select =document.getElementById(select_id);
1508           select.selectedIndex = -1;
1509           select.options.length = 0;
1510           select.options[0] =  new Option(notSet,"",false,false);
1511       });
1512
1513    },
1514
1515
1516		// Inital focus on 'url' field if link is of type URL.
1517		onFocus : function()
1518		{
1519			var linkType = this.getContentElement( 'info', 'linkType' ),
1520					urlField;
1521			if ( linkType && linkType.getValue() == 'url' )
1522			{
1523				urlField = this.getContentElement( 'info', 'url' );
1524				urlField.select();
1525			}
1526		}
1527	};
1528});
1529
1530/**
1531 * The Link Wizard
1532 *
1533 * @author Andreas Gohr <gohr@cosmocode.de>
1534 * @author Pierre Spring <pierre.spring@caillou.ch>
1535 */
1536var doku_linkwiz = {
1537    $wiz: null,
1538    $entry: null,
1539    result: null,
1540    timer: null,
1541    textArea: null,
1542    selected: null,
1543    $ck: null,
1544
1545    /**
1546     * Initialize the doku_linkwizard by creating the needed HTML
1547     * and attaching the eventhandlers
1548     */
1549    init: function($editor, ck){
1550        // position relative to the text area
1551        var pos = $editor.position();
1552        $ck = ck;
1553
1554        // create HTML Structure
1555        if(doku_linkwiz.$wiz)
1556            return;
1557        doku_linkwiz.$wiz = jQuery(document.createElement('div'))
1558               .dialog({
1559                   autoOpen: false,
1560                   draggable: true,
1561                   title: LANG.linkwiz,
1562                   resizable: false
1563               })
1564               .html(
1565                    '<div>'+LANG.linkto+' <input type="text" class="edit" id="link__wiz_entry" autocomplete="off" /></div>'+
1566                    '<div id="link__wiz_result"></div>'
1567                    )
1568               .parent()
1569               .attr('id','link__wiz')
1570               .css({
1571                    'position':    'absolute',
1572                    'top':         (pos.top+20)+'px',
1573                    'left':        (pos.left+80)+'px',
1574                    'z-index':      '20000'
1575                   })
1576               .hide()
1577               .appendTo('.dokuwiki:first');
1578
1579        doku_linkwiz.textArea = $editor[0];
1580        doku_linkwiz.result = jQuery('#link__wiz_result')[0];
1581
1582        // scrollview correction on arrow up/down gets easier
1583        jQuery(doku_linkwiz.result).css('position', 'relative');
1584
1585        doku_linkwiz.$entry = jQuery('#link__wiz_entry');
1586        if(JSINFO.namespace){
1587            doku_linkwiz.$entry.val(JSINFO.namespace+':');
1588        }
1589
1590        // attach event handlers
1591        jQuery('#link__wiz .ui-dialog-titlebar-close').click(doku_linkwiz.hide);
1592        doku_linkwiz.$entry.keyup(doku_linkwiz.onEntry);
1593        jQuery(doku_linkwiz.result).delegate('a', 'click', doku_linkwiz.onResultClick);
1594    },
1595
1596/**
1597     * handle all keyup events in the entry field
1598     */
1599    onEntry: function(e){
1600        if(e.keyCode == 37 || e.keyCode == 39){ //left/right
1601            return true; //ignore
1602        }
1603        if(e.keyCode == 27){ //Escape
1604            doku_linkwiz.hide();
1605            e.preventDefault();
1606            e.stopPropagation();
1607            return false;
1608        }
1609        if(e.keyCode == 38){ //Up
1610            doku_linkwiz.select(doku_linkwiz.selected -1);
1611            e.preventDefault();
1612            e.stopPropagation();
1613            return false;
1614        }
1615        if(e.keyCode == 40){ //Down
1616            doku_linkwiz.select(doku_linkwiz.selected +1);
1617            e.preventDefault();
1618            e.stopPropagation();
1619            return false;
1620        }
1621        if(e.keyCode == 13){ //Enter
1622            if(doku_linkwiz.selected > -1){
1623                var $obj = doku_linkwiz.$getResult(doku_linkwiz.selected);
1624                if($obj.length > 0){
1625                    doku_linkwiz.resultClick($obj.find('a')[0]);
1626                }
1627            }else if(doku_linkwiz.$entry.val()){
1628                doku_linkwiz.insertLink(doku_linkwiz.$entry.val());
1629            }
1630
1631            e.preventDefault();
1632            e.stopPropagation();
1633            return false;
1634        }
1635        doku_linkwiz.autocomplete();
1636    },
1637
1638    /**
1639     * Get one of the results by index
1640     *
1641     * @param   num int result div to return
1642     * @returns DOMObject or null
1643     */
1644    getResult: function(num){
1645        DEPRECATED('use doku_linkwiz.$getResult()[0] instead');
1646        return doku_linkwiz.$getResult()[0] || null;
1647    },
1648
1649    /**
1650     * Get one of the results by index
1651     *
1652     * @param   num int result div to return
1653     * @returns jQuery object
1654 */
1655    $getResult: function(num) {
1656        return jQuery(doku_linkwiz.result).find('div').eq(num);
1657    },
1658
1659    /**
1660     * Select the given result
1661     */
1662    select: function(num){
1663        if(num < 0){
1664            doku_linkwiz.deselect();
1665            return;
1666        }
1667
1668        var $obj = doku_linkwiz.$getResult(num);
1669        if ($obj.length === 0) {
1670            return;
1671        }
1672
1673        doku_linkwiz.deselect();
1674        $obj.addClass('selected');
1675
1676        // make sure the item is viewable in the scroll view
1677
1678        //getting child position within the parent
1679        var childPos = $obj.position().top;
1680        //getting difference between the childs top and parents viewable area
1681        var yDiff = childPos + $obj.outerHeight() - jQuery(doku_linkwiz.result).innerHeight();
1682
1683        if (childPos < 0) {
1684            //if childPos is above viewable area (that's why it goes negative)
1685            jQuery(doku_linkwiz.result)[0].scrollTop += childPos;
1686        } else if(yDiff > 0) {
1687            // if difference between childs top and parents viewable area is
1688            // greater than the height of a childDiv
1689            jQuery(doku_linkwiz.result)[0].scrollTop += yDiff;
1690        }
1691
1692        doku_linkwiz.selected = num;
1693    },
1694
1695    /**
1696     * deselect a result if any is selected
1697     */
1698    deselect: function(){
1699        if(doku_linkwiz.selected > -1){
1700            doku_linkwiz.$getResult(doku_linkwiz.selected).removeClass('selected');
1701        }
1702        doku_linkwiz.selected = -1;
1703    },
1704
1705    /**
1706     * Handle clicks in the result set an dispatch them to
1707     * resultClick()
1708     */
1709    onResultClick: function(e){
1710        if(!jQuery(this).is('a')) {
1711            return;
1712        }
1713        e.stopPropagation();
1714        e.preventDefault();
1715        doku_linkwiz.resultClick(this);
1716        return false;
1717    },
1718
1719    /**
1720     * Handles the "click" on a given result anchor
1721     */
1722    resultClick: function(a){
1723        doku_linkwiz.$entry.val(a.title);
1724        if(a.title == '' || a.title.substr(a.title.length-1) == ':'){
1725            doku_linkwiz.autocomplete_exec();
1726        }else{
1727            if (jQuery(a.nextSibling).is('span')) {
1728                doku_linkwiz.insertLink(a.nextSibling.innerHTML);
1729            }else{
1730                doku_linkwiz.insertLink('');
1731            }
1732        }
1733    },
1734
1735    /**
1736     * Insert the id currently in the entry box to the textarea,
1737     * replacing the current selection or at the cursor position.
1738     * When no selection is available the given title will be used
1739     * as link title instead
1740     */
1741    insertLink: function(title){
1742        var link = doku_linkwiz.$entry.val(),
1743            sel, stxt;
1744        if(!link) {
1745            return;
1746        }
1747        link = ':' + link.replace(/^:/,"");
1748        //insert link into field
1749        var dialog = CKEDITOR.dialog.getCurrent();
1750        dialog.getContentElement("info", "internal").setValue(link);
1751        if(title && oDokuWiki_FCKEditorInstance.useheading == 'y') {
1752          dialog.getContentElement("info", "internal_text").setValue(title);
1753        }
1754        else {
1755            var ltype = dialog.getValueOf( 'info', 'ilinkstyle' );
1756            if(ltype == 'page') {
1757                var link_ar = link.split(':',link);
1758                link = link_ar.pop();
1759            }
1760        dialog.getContentElement("info", "internal_text").setValue(link);
1761       }
1762
1763        doku_linkwiz.hide();
1764
1765        // reset the entry to the parent namespace
1766        doku_linkwiz.$entry.val(doku_linkwiz.$entry.val().replace(/[^:]*$/, ''));
1767    },
1768
1769    /**
1770     * Start the page/namespace lookup timer
1771     *
1772     * Calls autocomplete_exec when the timer runs out
1773     */
1774    autocomplete: function(){
1775        if(doku_linkwiz.timer !== null){
1776            window.clearTimeout(doku_linkwiz.timer);
1777            doku_linkwiz.timer = null;
1778        }
1779
1780        doku_linkwiz.timer = window.setTimeout(doku_linkwiz.autocomplete_exec,350);
1781    },
1782
1783    /**
1784     * Executes the AJAX call for the page/namespace lookup
1785     */
1786    autocomplete_exec: function(){
1787        var $res = jQuery(doku_linkwiz.result);
1788        doku_linkwiz.deselect();
1789        $res.html('<img src="'+DOKU_BASE+'lib/images/throbber.gif" alt="" width="16" height="16" />')
1790            .load(
1791            DOKU_BASE + 'lib/exe/ajax.php',
1792            {
1793                call: 'linkwiz',
1794                q: doku_linkwiz.$entry.val()
1795            }
1796        );
1797    },
1798
1799    /**
1800     * Show the link wizard
1801     */
1802    show: function(){
1803        doku_linkwiz.$wiz.show();
1804        doku_linkwiz.$entry.focus();
1805        doku_linkwiz.autocomplete();
1806
1807        // Move the cursor to the end of the input
1808        var temp = doku_linkwiz.$entry.val();
1809        doku_linkwiz.$entry.val('');
1810        doku_linkwiz.$entry.val(temp);
1811    },
1812
1813    /**
1814     * Hide the link wizard
1815     */
1816    hide: function(){
1817        doku_linkwiz.$wiz.hide();
1818        doku_linkwiz.textArea.focus();
1819    },
1820
1821    /**
1822     * Toggle the link wizard
1823     */
1824    toggle: function(){
1825        if(doku_linkwiz.$wiz.css('display') == 'none'){
1826            doku_linkwiz.show();
1827        }else{
1828            doku_linkwiz.hide();
1829        }
1830    }
1831};
1832