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>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'>></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