[ Index ] |
|
Code source de GeekLog 1.4.1 |
1 /* 2 * FCKeditor - The text editor for internet 3 * Copyright (C) 2003-2006 Frederico Caldeira Knabben 4 * 5 * Licensed under the terms of the GNU Lesser General Public License: 6 * http://www.opensource.org/licenses/lgpl-license.php 7 * 8 * For further information visit: 9 * http://www.fckeditor.net/ 10 * 11 * "Support Open Source software. What about a donation today?" 12 * 13 * File Name: fck_link.js 14 * Scripts related to the Link dialog window (see fck_link.html). 15 * 16 * File Authors: 17 * Frederico Caldeira Knabben (fredck@fckeditor.net) 18 * Dominik Pesch ?dom? (empty selection patch) (d.pesch@11com7.de) 19 */ 20 21 var oEditor = window.parent.InnerDialogLoaded() ; 22 var FCK = oEditor.FCK ; 23 var FCKLang = oEditor.FCKLang ; 24 var FCKConfig = oEditor.FCKConfig ; 25 26 //#### Dialog Tabs 27 28 // Set the dialog tabs. 29 window.parent.AddTab( 'Info', FCKLang.DlgLnkInfoTab ) ; 30 31 if ( !FCKConfig.LinkDlgHideTarget ) 32 window.parent.AddTab( 'Target', FCKLang.DlgLnkTargetTab, true ) ; 33 34 if ( FCKConfig.LinkUpload ) 35 window.parent.AddTab( 'Upload', FCKLang.DlgLnkUpload, true ) ; 36 37 if ( !FCKConfig.LinkDlgHideAdvanced ) 38 window.parent.AddTab( 'Advanced', FCKLang.DlgAdvancedTag ) ; 39 40 // Function called when a dialog tag is selected. 41 function OnDialogTabChange( tabCode ) 42 { 43 ShowE('divInfo' , ( tabCode == 'Info' ) ) ; 44 ShowE('divTarget' , ( tabCode == 'Target' ) ) ; 45 ShowE('divUpload' , ( tabCode == 'Upload' ) ) ; 46 ShowE('divAttribs' , ( tabCode == 'Advanced' ) ) ; 47 48 window.parent.SetAutoSize( true ) ; 49 } 50 51 //#### Regular Expressions library. 52 var oRegex = new Object() ; 53 54 oRegex.UriProtocol = new RegExp('') ; 55 oRegex.UriProtocol.compile( '^(((http|https|ftp|news):\/\/)|mailto:)', 'gi' ) ; 56 57 oRegex.UrlOnChangeProtocol = new RegExp('') ; 58 oRegex.UrlOnChangeProtocol.compile( '^(http|https|ftp|news)://(?=.)', 'gi' ) ; 59 60 oRegex.UrlOnChangeTestOther = new RegExp('') ; 61 //oRegex.UrlOnChangeTestOther.compile( '^(javascript:|#|/)', 'gi' ) ; 62 oRegex.UrlOnChangeTestOther.compile( '^((javascript:)|[#/\.])', 'gi' ) ; 63 64 oRegex.ReserveTarget = new RegExp('') ; 65 oRegex.ReserveTarget.compile( '^_(blank|self|top|parent)$', 'i' ) ; 66 67 oRegex.PopupUri = new RegExp('') ; 68 oRegex.PopupUri.compile( "^javascript:void\\(\\s*window.open\\(\\s*'([^']+)'\\s*,\\s*(?:'([^']*)'|null)\\s*,\\s*'([^']*)'\\s*\\)\\s*\\)\\s*$" ) ; 69 70 oRegex.PopupFeatures = new RegExp('') ; 71 oRegex.PopupFeatures.compile( '(?:^|,)([^=]+)=(\\d+|yes|no)', 'gi' ) ; 72 73 //#### Parser Functions 74 75 var oParser = new Object() ; 76 77 oParser.ParseEMailUrl = function( emailUrl ) 78 { 79 // Initializes the EMailInfo object. 80 var oEMailInfo = new Object() ; 81 oEMailInfo.Address = '' ; 82 oEMailInfo.Subject = '' ; 83 oEMailInfo.Body = '' ; 84 85 var oParts = emailUrl.match( /^([^\?]+)\??(.+)?/ ) ; 86 if ( oParts ) 87 { 88 // Set the e-mail address. 89 oEMailInfo.Address = oParts[1] ; 90 91 // Look for the optional e-mail parameters. 92 if ( oParts[2] ) 93 { 94 var oMatch = oParts[2].match( /(^|&)subject=([^&]+)/i ) ; 95 if ( oMatch ) oEMailInfo.Subject = unescape( oMatch[2] ) ; 96 97 oMatch = oParts[2].match( /(^|&)body=([^&]+)/i ) ; 98 if ( oMatch ) oEMailInfo.Body = unescape( oMatch[2] ) ; 99 } 100 } 101 102 return oEMailInfo ; 103 } 104 105 oParser.CreateEMailUri = function( address, subject, body ) 106 { 107 var sBaseUri = 'mailto:' + address ; 108 109 var sParams = '' ; 110 111 if ( subject.length > 0 ) 112 sParams = '?subject=' + escape( subject ) ; 113 114 if ( body.length > 0 ) 115 { 116 sParams += ( sParams.length == 0 ? '?' : '&' ) ; 117 sParams += 'body=' + escape( body ) ; 118 } 119 120 return sBaseUri + sParams ; 121 } 122 123 //#### Initialization Code 124 125 // oLink: The actual selected link in the editor. 126 var oLink = FCK.Selection.MoveToAncestorNode( 'A' ) ; 127 if ( oLink ) 128 FCK.Selection.SelectNode( oLink ) ; 129 130 window.onload = function() 131 { 132 // Translate the dialog box texts. 133 oEditor.FCKLanguageManager.TranslatePage(document) ; 134 135 // Fill the Anchor Names and Ids combos. 136 LoadAnchorNamesAndIds() ; 137 138 // Load the selected link information (if any). 139 LoadSelection() ; 140 141 // Update the dialog box. 142 SetLinkType( GetE('cmbLinkType').value ) ; 143 144 // Show/Hide the "Browse Server" button. 145 GetE('divBrowseServer').style.display = FCKConfig.LinkBrowser ? '' : 'none' ; 146 147 // Show the initial dialog content. 148 GetE('divInfo').style.display = '' ; 149 150 // Set the actual uploader URL. 151 if ( FCKConfig.LinkUpload ) 152 GetE('frmUpload').action = FCKConfig.LinkUploadURL ; 153 154 // Activate the "OK" button. 155 window.parent.SetOkButton( true ) ; 156 } 157 158 var bHasAnchors ; 159 160 function LoadAnchorNamesAndIds() 161 { 162 // Since version 2.0, the anchors are replaced in the DOM by IMGs so the user see the icon 163 // to edit them. So, we must look for that images now. 164 var aAnchors = new Array() ; 165 166 var oImages = oEditor.FCK.EditorDocument.getElementsByTagName( 'IMG' ) ; 167 for( var i = 0 ; i < oImages.length ; i++ ) 168 { 169 if ( oImages[i].getAttribute('_fckanchor') ) 170 aAnchors[ aAnchors.length ] = oEditor.FCK.GetRealElement( oImages[i] ) ; 171 } 172 173 var aIds = oEditor.FCKTools.GetAllChildrenIds( oEditor.FCK.EditorDocument.body ) ; 174 175 bHasAnchors = ( aAnchors.length > 0 || aIds.length > 0 ) ; 176 177 for ( var i = 0 ; i < aAnchors.length ; i++ ) 178 { 179 var sName = aAnchors[i].name ; 180 if ( sName && sName.length > 0 ) 181 oEditor.FCKTools.AddSelectOption( GetE('cmbAnchorName'), sName, sName ) ; 182 } 183 184 for ( var i = 0 ; i < aIds.length ; i++ ) 185 { 186 oEditor.FCKTools.AddSelectOption( GetE('cmbAnchorId'), aIds[i], aIds[i] ) ; 187 } 188 189 ShowE( 'divSelAnchor' , bHasAnchors ) ; 190 ShowE( 'divNoAnchor' , !bHasAnchors ) ; 191 } 192 193 function LoadSelection() 194 { 195 if ( !oLink ) return ; 196 197 var sType = 'url' ; 198 199 // Get the actual Link href. 200 var sHRef = oLink.getAttribute( '_fcksavedurl' ) ; 201 if ( !sHRef || sHRef.length == 0 ) 202 sHRef = oLink.getAttribute( 'href' , 2 ) + '' ; 203 204 // TODO: Wait stable version and remove the following commented lines. 205 // if ( sHRef.startsWith( FCK.BaseUrl ) ) 206 // sHRef = sHRef.remove( 0, FCK.BaseUrl.length ) ; 207 208 // Look for a popup javascript link. 209 var oPopupMatch = oRegex.PopupUri.exec( sHRef ) ; 210 if( oPopupMatch ) 211 { 212 GetE('cmbTarget').value = 'popup' ; 213 sHRef = oPopupMatch[1] ; 214 FillPopupFields( oPopupMatch[2], oPopupMatch[3] ) ; 215 SetTarget( 'popup' ) ; 216 } 217 218 // Search for the protocol. 219 var sProtocol = oRegex.UriProtocol.exec( sHRef ) ; 220 221 if ( sProtocol ) 222 { 223 sProtocol = sProtocol[0].toLowerCase() ; 224 GetE('cmbLinkProtocol').value = sProtocol ; 225 226 // Remove the protocol and get the remainig URL. 227 var sUrl = sHRef.replace( oRegex.UriProtocol, '' ) ; 228 229 if ( sProtocol == 'mailto:' ) // It is an e-mail link. 230 { 231 sType = 'email' ; 232 233 var oEMailInfo = oParser.ParseEMailUrl( sUrl ) ; 234 GetE('txtEMailAddress').value = oEMailInfo.Address ; 235 GetE('txtEMailSubject').value = oEMailInfo.Subject ; 236 GetE('txtEMailBody').value = oEMailInfo.Body ; 237 } 238 else // It is a normal link. 239 { 240 sType = 'url' ; 241 GetE('txtUrl').value = sUrl ; 242 } 243 } 244 else if ( sHRef.substr(0,1) == '#' && sHRef.length > 1 ) // It is an anchor link. 245 { 246 sType = 'anchor' ; 247 GetE('cmbAnchorName').value = GetE('cmbAnchorId').value = sHRef.substr(1) ; 248 } 249 else // It is another type of link. 250 { 251 sType = 'url' ; 252 253 GetE('cmbLinkProtocol').value = '' ; 254 GetE('txtUrl').value = sHRef ; 255 } 256 257 if ( !oPopupMatch ) 258 { 259 // Get the target. 260 var sTarget = oLink.target ; 261 262 if ( sTarget && sTarget.length > 0 ) 263 { 264 if ( oRegex.ReserveTarget.test( sTarget ) ) 265 { 266 sTarget = sTarget.toLowerCase() ; 267 GetE('cmbTarget').value = sTarget ; 268 } 269 else 270 GetE('cmbTarget').value = 'frame' ; 271 GetE('txtTargetFrame').value = sTarget ; 272 } 273 } 274 275 // Get Advances Attributes 276 GetE('txtAttId').value = oLink.id ; 277 GetE('txtAttName').value = oLink.name ; 278 GetE('cmbAttLangDir').value = oLink.dir ; 279 GetE('txtAttLangCode').value = oLink.lang ; 280 GetE('txtAttAccessKey').value = oLink.accessKey ; 281 GetE('txtAttTabIndex').value = oLink.tabIndex <= 0 ? '' : oLink.tabIndex ; 282 GetE('txtAttTitle').value = oLink.title ; 283 GetE('txtAttContentType').value = oLink.type ; 284 GetE('txtAttCharSet').value = oLink.charset ; 285 286 if ( oEditor.FCKBrowserInfo.IsIE ) 287 { 288 GetE('txtAttClasses').value = oLink.getAttribute('className',2) || '' ; 289 GetE('txtAttStyle').value = oLink.style.cssText ; 290 } 291 else 292 { 293 GetE('txtAttClasses').value = oLink.getAttribute('class',2) || '' ; 294 GetE('txtAttStyle').value = oLink.getAttribute('style',2) ; 295 } 296 297 // Update the Link type combo. 298 GetE('cmbLinkType').value = sType ; 299 } 300 301 //#### Link type selection. 302 function SetLinkType( linkType ) 303 { 304 ShowE('divLinkTypeUrl' , (linkType == 'url') ) ; 305 ShowE('divLinkTypeAnchor' , (linkType == 'anchor') ) ; 306 ShowE('divLinkTypeEMail' , (linkType == 'email') ) ; 307 308 if ( !FCKConfig.LinkDlgHideTarget ) 309 window.parent.SetTabVisibility( 'Target' , (linkType == 'url') ) ; 310 311 if ( FCKConfig.LinkUpload ) 312 window.parent.SetTabVisibility( 'Upload' , (linkType == 'url') ) ; 313 314 if ( !FCKConfig.LinkDlgHideAdvanced ) 315 window.parent.SetTabVisibility( 'Advanced' , (linkType != 'anchor' || bHasAnchors) ) ; 316 317 if ( linkType == 'email' ) 318 window.parent.SetAutoSize( true ) ; 319 } 320 321 //#### Target type selection. 322 function SetTarget( targetType ) 323 { 324 GetE('tdTargetFrame').style.display = ( targetType == 'popup' ? 'none' : '' ) ; 325 GetE('tdPopupName').style.display = 326 GetE('tablePopupFeatures').style.display = ( targetType == 'popup' ? '' : 'none' ) ; 327 328 switch ( targetType ) 329 { 330 case "_blank" : 331 case "_self" : 332 case "_parent" : 333 case "_top" : 334 GetE('txtTargetFrame').value = targetType ; 335 break ; 336 case "" : 337 GetE('txtTargetFrame').value = '' ; 338 break ; 339 } 340 341 if ( targetType == 'popup' ) 342 window.parent.SetAutoSize( true ) ; 343 } 344 345 //#### Called while the user types the URL. 346 function OnUrlChange() 347 { 348 var sUrl = GetE('txtUrl').value ; 349 var sProtocol = oRegex.UrlOnChangeProtocol.exec( sUrl ) ; 350 351 if ( sProtocol ) 352 { 353 sUrl = sUrl.substr( sProtocol[0].length ) ; 354 GetE('txtUrl').value = sUrl ; 355 GetE('cmbLinkProtocol').value = sProtocol[0].toLowerCase() ; 356 } 357 else if ( oRegex.UrlOnChangeTestOther.test( sUrl ) ) 358 { 359 GetE('cmbLinkProtocol').value = '' ; 360 } 361 } 362 363 //#### Called while the user types the target name. 364 function OnTargetNameChange() 365 { 366 var sFrame = GetE('txtTargetFrame').value ; 367 368 if ( sFrame.length == 0 ) 369 GetE('cmbTarget').value = '' ; 370 else if ( oRegex.ReserveTarget.test( sFrame ) ) 371 GetE('cmbTarget').value = sFrame.toLowerCase() ; 372 else 373 GetE('cmbTarget').value = 'frame' ; 374 } 375 376 //#### Builds the javascript URI to open a popup to the specified URI. 377 function BuildPopupUri( uri ) 378 { 379 var oReg = new RegExp( "'", "g" ) ; 380 var sWindowName = "'" + GetE('txtPopupName').value.replace(oReg, "\\'") + "'" ; 381 382 var sFeatures = '' ; 383 var aChkFeatures = document.getElementsByName('chkFeature') ; 384 for ( var i = 0 ; i < aChkFeatures.length ; i++ ) 385 { 386 if ( i > 0 ) sFeatures += ',' ; 387 sFeatures += aChkFeatures[i].value + '=' + ( aChkFeatures[i].checked ? 'yes' : 'no' ) ; 388 } 389 390 if ( GetE('txtPopupWidth').value.length > 0 ) sFeatures += ',width=' + GetE('txtPopupWidth').value ; 391 if ( GetE('txtPopupHeight').value.length > 0 ) sFeatures += ',height=' + GetE('txtPopupHeight').value ; 392 if ( GetE('txtPopupLeft').value.length > 0 ) sFeatures += ',left=' + GetE('txtPopupLeft').value ; 393 if ( GetE('txtPopupTop').value.length > 0 ) sFeatures += ',top=' + GetE('txtPopupTop').value ; 394 395 return ( "javascript:void(window.open('" + uri + "'," + sWindowName + ",'" + sFeatures + "'))" ) ; 396 } 397 398 //#### Fills all Popup related fields. 399 function FillPopupFields( windowName, features ) 400 { 401 if ( windowName ) 402 GetE('txtPopupName').value = windowName ; 403 404 var oFeatures = new Object() ; 405 var oFeaturesMatch ; 406 while( ( oFeaturesMatch = oRegex.PopupFeatures.exec( features ) ) != null ) 407 { 408 var sValue = oFeaturesMatch[2] ; 409 if ( sValue == ( 'yes' || '1' ) ) 410 oFeatures[ oFeaturesMatch[1] ] = true ; 411 else if ( ! isNaN( sValue ) && sValue != 0 ) 412 oFeatures[ oFeaturesMatch[1] ] = sValue ; 413 } 414 415 // Update all features check boxes. 416 var aChkFeatures = document.getElementsByName('chkFeature') ; 417 for ( var i = 0 ; i < aChkFeatures.length ; i++ ) 418 { 419 if ( oFeatures[ aChkFeatures[i].value ] ) 420 aChkFeatures[i].checked = true ; 421 } 422 423 // Update position and size text boxes. 424 if ( oFeatures['width'] ) GetE('txtPopupWidth').value = oFeatures['width'] ; 425 if ( oFeatures['height'] ) GetE('txtPopupHeight').value = oFeatures['height'] ; 426 if ( oFeatures['left'] ) GetE('txtPopupLeft').value = oFeatures['left'] ; 427 if ( oFeatures['top'] ) GetE('txtPopupTop').value = oFeatures['top'] ; 428 } 429 430 //#### The OK button was hit. 431 function Ok() 432 { 433 var sUri, sInnerHtml ; 434 435 switch ( GetE('cmbLinkType').value ) 436 { 437 case 'url' : 438 sUri = GetE('txtUrl').value ; 439 440 if ( sUri.length == 0 ) 441 { 442 alert( FCKLang.DlnLnkMsgNoUrl ) ; 443 return false ; 444 } 445 446 sUri = GetE('cmbLinkProtocol').value + sUri ; 447 448 if( GetE('cmbTarget').value == 'popup' ) 449 sUri = BuildPopupUri( sUri ) ; 450 451 break ; 452 453 case 'email' : 454 sUri = GetE('txtEMailAddress').value ; 455 456 if ( sUri.length == 0 ) 457 { 458 alert( FCKLang.DlnLnkMsgNoEMail ) ; 459 return false ; 460 } 461 462 sUri = oParser.CreateEMailUri( 463 sUri, 464 GetE('txtEMailSubject').value, 465 GetE('txtEMailBody').value ) ; 466 break ; 467 468 case 'anchor' : 469 var sAnchor = GetE('cmbAnchorName').value ; 470 if ( sAnchor.length == 0 ) sAnchor = GetE('cmbAnchorId').value ; 471 472 if ( sAnchor.length == 0 ) 473 { 474 alert( FCKLang.DlnLnkMsgNoAnchor ) ; 475 return false ; 476 } 477 478 sUri = '#' + sAnchor ; 479 break ; 480 } 481 482 // No link selected, so try to create one. 483 if ( !oLink ) 484 oLink = oEditor.FCK.CreateLink( sUri ) ; 485 486 if ( oLink ) 487 sInnerHtml = oLink.innerHTML ; // Save the innerHTML (IE changes it if it is like a URL). 488 else 489 { 490 // If no selection, use the uri as the link text (by dom, 2006-05-26) 491 492 sInnerHtml = sUri; 493 494 // try to built better text for empty link 495 switch (GetE('cmbLinkType').value) 496 { 497 // anchor: use old behavior --> return true 498 case 'anchor': 499 sInnerHtml = sInnerHtml.replace( /^#/, '' ) ; 500 break; 501 502 // url: try to get path 503 case 'url': 504 var oLinkPathRegEx = new RegExp("//?([^?\"']+)([?].*)?$"); 505 var asLinkPath = oLinkPathRegEx.exec( sUri ); 506 if (asLinkPath != null) 507 sInnerHtml = asLinkPath[1]; // use matched path 508 break; 509 510 // mailto: try to get email address 511 case 'email': 512 sInnerHtml = GetE('txtEMailAddress').value 513 break; 514 } 515 516 // built new anchor and add link text 517 oLink = oEditor.FCK.CreateElement( 'a' ) ; 518 } 519 520 oEditor.FCKUndo.SaveUndoStep() ; 521 522 oLink.href = sUri ; 523 SetAttribute( oLink, '_fcksavedurl', sUri ) ; 524 525 oLink.innerHTML = sInnerHtml ; // Set (or restore) the innerHTML 526 527 // Target 528 if( GetE('cmbTarget').value != 'popup' ) 529 SetAttribute( oLink, 'target', GetE('txtTargetFrame').value ) ; 530 else 531 SetAttribute( oLink, 'target', null ) ; 532 533 // Advances Attributes 534 SetAttribute( oLink, 'id' , GetE('txtAttId').value ) ; 535 SetAttribute( oLink, 'name' , GetE('txtAttName').value ) ; // No IE. Set but doesnt't update the outerHTML. 536 SetAttribute( oLink, 'dir' , GetE('cmbAttLangDir').value ) ; 537 SetAttribute( oLink, 'lang' , GetE('txtAttLangCode').value ) ; 538 SetAttribute( oLink, 'accesskey', GetE('txtAttAccessKey').value ) ; 539 SetAttribute( oLink, 'tabindex' , ( GetE('txtAttTabIndex').value > 0 ? GetE('txtAttTabIndex').value : null ) ) ; 540 SetAttribute( oLink, 'title' , GetE('txtAttTitle').value ) ; 541 SetAttribute( oLink, 'type' , GetE('txtAttContentType').value ) ; 542 SetAttribute( oLink, 'charset' , GetE('txtAttCharSet').value ) ; 543 544 if ( oEditor.FCKBrowserInfo.IsIE ) 545 { 546 SetAttribute( oLink, 'className', GetE('txtAttClasses').value ) ; 547 oLink.style.cssText = GetE('txtAttStyle').value ; 548 } 549 else 550 { 551 SetAttribute( oLink, 'class', GetE('txtAttClasses').value ) ; 552 SetAttribute( oLink, 'style', GetE('txtAttStyle').value ) ; 553 } 554 555 // Select the link. 556 oEditor.FCKSelection.SelectNode(oLink); 557 558 return true ; 559 } 560 561 function BrowseServer() 562 { 563 OpenFileBrowser( FCKConfig.LinkBrowserURL, FCKConfig.LinkBrowserWindowWidth, FCKConfig.LinkBrowserWindowHeight ) ; 564 } 565 566 function SetUrl( url ) 567 { 568 document.getElementById('txtUrl').value = url ; 569 OnUrlChange() ; 570 window.parent.SetSelectedTab( 'Info' ) ; 571 } 572 573 function OnUploadCompleted( errorNumber, fileUrl, fileName, customMsg ) 574 { 575 switch ( errorNumber ) 576 { 577 case 0 : // No errors 578 alert( 'Your file has been successfully uploaded' ) ; 579 break ; 580 case 1 : // Custom error 581 alert( customMsg ) ; 582 return ; 583 case 101 : // Custom warning 584 alert( customMsg ) ; 585 break ; 586 case 201 : 587 alert( 'A file with the same name is already available. The uploaded file has been renamed to "' + fileName + '"' ) ; 588 break ; 589 case 202 : 590 alert( 'Invalid file type' ) ; 591 return ; 592 case 203 : 593 alert( "Security error. You probably don't have enough permissions to upload. Please check your server." ) ; 594 return ; 595 default : 596 alert( 'Error on file upload. Error number: ' + errorNumber ) ; 597 return ; 598 } 599 600 SetUrl( fileUrl ) ; 601 GetE('frmUpload').reset() ; 602 } 603 604 var oUploadAllowedExtRegex = new RegExp( FCKConfig.LinkUploadAllowedExtensions, 'i' ) ; 605 var oUploadDeniedExtRegex = new RegExp( FCKConfig.LinkUploadDeniedExtensions, 'i' ) ; 606 607 function CheckUpload() 608 { 609 var sFile = GetE('txtUploadFile').value ; 610 611 if ( sFile.length == 0 ) 612 { 613 alert( 'Please select a file to upload' ) ; 614 return false ; 615 } 616 617 if ( ( FCKConfig.LinkUploadAllowedExtensions.length > 0 && !oUploadAllowedExtRegex.test( sFile ) ) || 618 ( FCKConfig.LinkUploadDeniedExtensions.length > 0 && oUploadDeniedExtRegex.test( sFile ) ) ) 619 { 620 OnUploadCompleted( 202 ) ; 621 return false ; 622 } 623 624 return true ; 625 }
titre
Description
Corps
titre
Description
Corps
titre
Description
Corps
titre
Corps
Généré le : Wed Nov 21 12:27:40 2007 | par Balluche grâce à PHPXref 0.7 |
![]() |