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