[ Index ] |
PHP Cross Reference of osCMax 2.0.4 |
[Summary view] [Print] [Text view]
1 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"> 2 <!-- 3 * FCKeditor - The text editor for Internet - http://www.fckeditor.net 4 * Copyright (C) 2003-2008 Frederico Caldeira Knabben 5 * 6 * == BEGIN LICENSE == 7 * 8 * Licensed under the terms of any of the following licenses at your 9 * choice: 10 * 11 * - GNU General Public License Version 2 or later (the "GPL") 12 * http://www.gnu.org/licenses/gpl.html 13 * 14 * - GNU Lesser General Public License Version 2.1 or later (the "LGPL") 15 * http://www.gnu.org/licenses/lgpl.html 16 * 17 * - Mozilla Public License Version 1.1 or later (the "MPL") 18 * http://www.mozilla.org/MPL/MPL-1.1.html 19 * 20 * == END LICENSE == 21 * 22 * "Find" and "Replace" dialog box window. 23 --> 24 <html xmlns="http://www.w3.org/1999/xhtml"> 25 <head> 26 <title></title> 27 <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> 28 <meta content="noindex, nofollow" name="robots" /> 29 <script src="common/fck_dialog_common.js" type="text/javascript"></script> 30 <script type="text/javascript"> 31 32 var dialog = window.parent ; 33 var oEditor = dialog.InnerDialogLoaded() ; 34 var dialogArguments = dialog.Args() ; 35 36 var FCKLang = oEditor.FCKLang ; 37 var FCKDomTools = oEditor.FCKDomTools ; 38 var FCKDomRange = oEditor.FCKDomRange ; 39 var FCKListsLib = oEditor.FCKListsLib ; 40 var FCKTools = oEditor.FCKTools ; 41 var EditorDocument = oEditor.FCK.EditorDocument ; 42 var HighlightStyle = oEditor.FCKStyles.GetStyle( '_FCK_SelectionHighlight' ) ; 43 44 dialog.AddTab( 'Find', FCKLang.DlgFindTitle ) ; 45 dialog.AddTab( 'Replace', FCKLang.DlgReplaceTitle ) ; 46 var idMap = {} ; 47 48 function OnDialogTabChange( tabCode ) 49 { 50 ShowE( 'divFind', ( tabCode == 'Find' ) ) ; 51 ShowE( 'divReplace', ( tabCode == 'Replace' ) ) ; 52 idMap['FindText'] = 'txtFind' + tabCode ; 53 idMap['CheckCase'] = 'chkCase' + tabCode ; 54 idMap['CheckWord'] = 'chkWord' + tabCode ; 55 56 if ( tabCode == 'Replace' ) 57 dialog.SetAutoSize( true ) ; 58 } 59 60 GetNextNonEmptyTextNode = function( node, stopNode ) 61 { 62 while ( ( node = FCKDomTools.GetNextSourceNode( node, false, 3, stopNode ) ) && node && node.length < 1 ) 63 1 ; 64 return node ; 65 } 66 67 CharacterCursor = function( arg ) 68 { 69 if ( arg.nodeType && arg.nodeType == 9 ) 70 { 71 this._textNode = GetNextNonEmptyTextNode( arg.body, arg.documentElement ) ; 72 this._offset = 0 ; 73 this._doc = arg ; 74 } 75 else 76 { 77 this._textNode = arguments[0] ; 78 this._offset = arguments[1] ; 79 this._doc = FCKTools.GetElementDocument( arguments[0] ) ; 80 } 81 } 82 CharacterCursor.prototype = 83 { 84 GetCharacter : function() 85 { 86 return ( this._textNode && this._textNode.nodeValue.charAt( this._offset ) ) || null ; 87 }, 88 89 // Non-normalized. 90 GetTextNode : function() 91 { 92 return this._textNode ; 93 }, 94 95 // Non-normalized. 96 GetIndex : function() 97 { 98 return this._offset ; 99 }, 100 101 // Return value means whehther we've crossed a line break or a paragraph boundary. 102 MoveNext : function() 103 { 104 if ( this._offset < this._textNode.length - 1 ) 105 { 106 this._offset++ ; 107 return false ; 108 } 109 110 var crossed = false ; 111 var curNode = this._textNode ; 112 while ( ( curNode = FCKDomTools.GetNextSourceNode( curNode ) ) 113 && curNode && ( curNode.nodeType != 3 || curNode.length < 1 ) ) 114 { 115 var tag = curNode.nodeName.toLowerCase() ; 116 if ( FCKListsLib.BlockElements[tag] || tag == 'br' ) 117 crossed = true ; 118 } 119 120 this._textNode = curNode ; 121 this._offset = 0 ; 122 return crossed ; 123 }, 124 125 // Return value means whehther we've crossed a line break or a paragraph boundary. 126 MoveBack : function() 127 { 128 if ( this._offset > 0 && this._textNode.length > 0 ) 129 { 130 this._offset = Math.min( this._offset - 1, this._textNode.length - 1 ) ; 131 return false ; 132 } 133 134 var crossed = false ; 135 var curNode = this._textNode ; 136 while ( ( curNode = FCKDomTools.GetPreviousSourceNode( curNode ) ) 137 && curNode && ( curNode.nodeType != 3 || curNode.length < 1 ) ) 138 { 139 var tag = curNode.nodeName.toLowerCase() ; 140 if ( FCKListsLib.BlockElements[tag] || tag == 'br' ) 141 crossed = true ; 142 } 143 144 this._textNode = curNode ; 145 this._offset = curNode.length - 1 ; 146 return crossed ; 147 }, 148 149 Clone : function() 150 { 151 return new CharacterCursor( this._textNode, this._offset ) ; 152 } 153 } ; 154 155 CharacterRange = function( initCursor, maxLength ) 156 { 157 this._cursors = initCursor.push ? initCursor : [initCursor] ; 158 this._maxLength = maxLength ; 159 this._highlightRange = null ; 160 } 161 CharacterRange.prototype = 162 { 163 ToDomRange : function() 164 { 165 var firstCursor = this._cursors[0] ; 166 var lastCursor = this._cursors[ this._cursors.length - 1 ] ; 167 var domRange = new FCKDomRange( FCKTools.GetElementWindow( firstCursor.GetTextNode() ) ) ; 168 var w3cRange = domRange._Range = domRange.CreateRange() ; 169 w3cRange.setStart( firstCursor.GetTextNode(), firstCursor.GetIndex() ) ; 170 w3cRange.setEnd( lastCursor.GetTextNode(), lastCursor.GetIndex() + 1 ) ; 171 domRange._UpdateElementInfo() ; 172 return domRange ; 173 }, 174 175 Highlight : function() 176 { 177 if ( this._cursors.length < 1 ) 178 return ; 179 180 var domRange = this.ToDomRange() ; 181 HighlightStyle.ApplyToRange( domRange, false, true ) ; 182 this._highlightRange = domRange ; 183 184 var charRange = CharacterRange.CreateFromDomRange( domRange ) ; 185 var focusNode = domRange.StartNode ; 186 if ( focusNode.nodeType != 1 ) 187 focusNode = focusNode.parentNode ; 188 FCKDomTools.ScrollIntoView( focusNode, false ) ; 189 this._cursors = charRange._cursors ; 190 }, 191 192 RemoveHighlight : function() 193 { 194 if ( this._highlightRange ) 195 { 196 HighlightStyle.RemoveFromRange( this._highlightRange, false, true ) ; 197 var charRange = CharacterRange.CreateFromDomRange( this._highlightRange ) ; 198 this._cursors = charRange._cursors ; 199 this._highlightRange = null ; 200 } 201 }, 202 203 GetHighlightDomRange : function() 204 { 205 return this._highlightRange; 206 }, 207 208 MoveNext : function() 209 { 210 var next = this._cursors[ this._cursors.length - 1 ].Clone() ; 211 var retval = next.MoveNext() ; 212 if ( retval ) 213 this._cursors = [] ; 214 this._cursors.push( next ) ; 215 if ( this._cursors.length > this._maxLength ) 216 this._cursors.shift() ; 217 return retval ; 218 }, 219 220 MoveBack : function() 221 { 222 var prev = this._cursors[0].Clone() ; 223 var retval = prev.MoveBack() ; 224 if ( retval ) 225 this._cursors = [] ; 226 this._cursors.unshift( prev ) ; 227 if ( this._cursors.length > this._maxLength ) 228 this._cursors.pop() ; 229 return retval ; 230 }, 231 232 GetEndCharacter : function() 233 { 234 if ( this._cursors.length < 1 ) 235 return null ; 236 var retval = this._cursors[ this._cursors.length - 1 ].GetCharacter() ; 237 return retval ; 238 }, 239 240 GetNextRange : function( len ) 241 { 242 if ( this._cursors.length == 0 ) 243 return null ; 244 var cur = this._cursors[ this._cursors.length - 1 ].Clone() ; 245 cur.MoveNext() ; 246 return new CharacterRange( cur, len ) ; 247 }, 248 249 GetCursors : function() 250 { 251 return this._cursors ; 252 } 253 } ; 254 255 CharacterRange.CreateFromDomRange = function( domRange ) 256 { 257 var w3cRange = domRange._Range ; 258 var startContainer = w3cRange.startContainer ; 259 var endContainer = w3cRange.endContainer ; 260 var startTextNode, startIndex, endTextNode, endIndex ; 261 262 if ( startContainer.nodeType == 3 ) 263 { 264 startTextNode = startContainer ; 265 startIndex = w3cRange.startOffset ; 266 } 267 else if ( domRange.StartNode.nodeType == 3 ) 268 { 269 startTextNode = domRange.StartNode ; 270 startIndex = 0 ; 271 } 272 else 273 { 274 startTextNode = GetNextNonEmptyTextNode( domRange.StartNode, domRange.StartNode.parentNode ) ; 275 if ( !startTextNode ) 276 return null ; 277 startIndex = 0 ; 278 } 279 280 if ( endContainer.nodeType == 3 && w3cRange.endOffset > 0 ) 281 { 282 endTextNode = endContainer ; 283 endIndex = w3cRange.endOffset - 1 ; 284 } 285 else 286 { 287 endTextNode = domRange.EndNode ; 288 while ( endTextNode.nodeType != 3 ) 289 endTextNode = endTextNode.lastChild ; 290 endIndex = endTextNode.length - 1 ; 291 } 292 293 var cursors = [] ; 294 var current = new CharacterCursor( startTextNode, startIndex ) ; 295 cursors.push( current ) ; 296 if ( !( current.GetTextNode() == endTextNode && current.GetIndex() == endIndex ) && !domRange.CheckIsEmpty() ) 297 { 298 do 299 { 300 current = current.Clone() ; 301 current.MoveNext() ; 302 cursors.push( current ) ; 303 } 304 while ( !( current.GetTextNode() == endTextNode && current.GetIndex() == endIndex ) ) ; 305 } 306 307 return new CharacterRange( cursors, cursors.length ) ; 308 } 309 310 // Knuth-Morris-Pratt Algorithm for stream input 311 KMP_NOMATCH = 0 ; 312 KMP_ADVANCED = 1 ; 313 KMP_MATCHED = 2 ; 314 KmpMatch = function( pattern, ignoreCase ) 315 { 316 var overlap = [ -1 ] ; 317 for ( var i = 0 ; i < pattern.length ; i++ ) 318 { 319 overlap.push( overlap[i] + 1 ) ; 320 while ( overlap[ i + 1 ] > 0 && pattern.charAt( i ) != pattern.charAt( overlap[ i + 1 ] - 1 ) ) 321 overlap[ i + 1 ] = overlap[ overlap[ i + 1 ] - 1 ] + 1 ; 322 } 323 this._Overlap = overlap ; 324 this._State = 0 ; 325 this._IgnoreCase = ( ignoreCase === true ) ; 326 if ( ignoreCase ) 327 this.Pattern = pattern.toLowerCase(); 328 else 329 this.Pattern = pattern ; 330 } 331 KmpMatch.prototype = { 332 FeedCharacter : function( c ) 333 { 334 if ( this._IgnoreCase ) 335 c = c.toLowerCase(); 336 337 while ( true ) 338 { 339 if ( c == this.Pattern.charAt( this._State ) ) 340 { 341 this._State++ ; 342 if ( this._State == this.Pattern.length ) 343 { 344 // found a match, start over, don't care about partial matches involving the current match 345 this._State = 0; 346 return KMP_MATCHED; 347 } 348 return KMP_ADVANCED ; 349 } 350 else if ( this._State == 0 ) 351 return KMP_NOMATCH; 352 else 353 this._State = this._Overlap[ this._State ]; 354 } 355 356 return null ; 357 }, 358 359 Reset : function() 360 { 361 this._State = 0 ; 362 } 363 }; 364 365 // Place a range at the start of document. 366 function OnLoad() 367 { 368 // First of all, translate the dialog box texts. 369 oEditor.FCKLanguageManager.TranslatePage( document ) ; 370 371 // Show the appropriate tab at startup. 372 if ( dialogArguments.CustomValue == 'Find' ) 373 { 374 dialog.SetSelectedTab( 'Find' ) ; 375 dialog.SetAutoSize( true ) ; 376 } 377 else 378 dialog.SetSelectedTab( 'Replace' ) ; 379 380 SelectField( 'txtFind' + dialogArguments.CustomValue ) ; 381 } 382 383 function btnStat() 384 { 385 GetE('btnReplace').disabled = 386 GetE('btnReplaceAll').disabled = 387 GetE('btnFind').disabled = 388 ( GetE(idMap["FindText"]).value.length == 0 ) ; 389 } 390 391 function btnStatDelayed() 392 { 393 setTimeout( btnStat, 1 ) ; 394 } 395 396 function GetSearchString() 397 { 398 return GetE(idMap['FindText']).value ; 399 } 400 401 function GetReplaceString() 402 { 403 return GetE("txtReplace").value ; 404 } 405 406 function GetCheckCase() 407 { 408 return !! ( GetE(idMap['CheckCase']).checked ) ; 409 } 410 411 function GetMatchWord() 412 { 413 return !! ( GetE(idMap['CheckWord']).checked ) ; 414 } 415 416 /* Is this character a unicode whitespace or a punctuation mark? 417 * References: 418 * http://unicode.org/Public/UNIDATA/PropList.txt (whitespaces) 419 * http://php.chinaunix.net/manual/tw/ref.regex.php (punctuation marks) 420 */ 421 function CheckIsWordSeparator( c ) 422 { 423 var code = c.charCodeAt( 0 ); 424 if ( code >= 9 && code <= 0xd ) 425 return true; 426 if ( code >= 0x2000 && code <= 0x200a ) 427 return true; 428 switch ( code ) 429 { 430 case 0x20: 431 case 0x85: 432 case 0xa0: 433 case 0x1680: 434 case 0x180e: 435 case 0x2028: 436 case 0x2029: 437 case 0x202f: 438 case 0x205f: 439 case 0x3000: 440 return true; 441 default: 442 } 443 return /[.,"'?!;:]/.test( c ) ; 444 } 445 446 FindRange = null ; 447 function _Find() 448 { 449 var searchString = GetSearchString() ; 450 if ( !FindRange ) 451 FindRange = new CharacterRange( new CharacterCursor( EditorDocument ), searchString.length ) ; 452 else 453 { 454 FindRange.RemoveHighlight() ; 455 FindRange = FindRange.GetNextRange( searchString.length ) ; 456 } 457 var matcher = new KmpMatch( searchString, ! GetCheckCase() ) ; 458 var matchState = KMP_NOMATCH ; 459 var character = '%' ; 460 461 while ( character != null ) 462 { 463 while ( ( character = FindRange.GetEndCharacter() ) ) 464 { 465 matchState = matcher.FeedCharacter( character ) ; 466 if ( matchState == KMP_MATCHED ) 467 break ; 468 if ( FindRange.MoveNext() ) 469 matcher.Reset() ; 470 } 471 472 if ( matchState == KMP_MATCHED ) 473 { 474 if ( GetMatchWord() ) 475 { 476 var cursors = FindRange.GetCursors() ; 477 var head = cursors[ cursors.length - 1 ].Clone() ; 478 var tail = cursors[0].Clone() ; 479 if ( !head.MoveNext() && !CheckIsWordSeparator( head.GetCharacter() ) ) 480 continue ; 481 if ( !tail.MoveBack() && !CheckIsWordSeparator( tail.GetCharacter() ) ) 482 continue ; 483 } 484 485 FindRange.Highlight() ; 486 return true ; 487 } 488 } 489 490 FindRange = null ; 491 return false ; 492 } 493 494 function Find() 495 { 496 if ( ! _Find() ) 497 alert( FCKLang.DlgFindNotFoundMsg ) ; 498 } 499 500 function Replace() 501 { 502 var saveUndoStep = function( selectRange ) 503 { 504 var ieRange ; 505 if ( oEditor.FCKBrowserInfo.IsIE ) 506 ieRange = document.selection.createRange() ; 507 508 selectRange.Select() ; 509 oEditor.FCKUndo.SaveUndoStep() ; 510 var cloneRange = selectRange.Clone() ; 511 cloneRange.Collapse( false ) ; 512 cloneRange.Select() ; 513 514 if ( ieRange ) 515 setTimeout( function(){ ieRange.select() ; }, 1 ) ; 516 } 517 518 if ( FindRange && FindRange.GetHighlightDomRange() ) 519 { 520 var range = FindRange.GetHighlightDomRange() ; 521 var bookmark = range.CreateBookmark() ; 522 FindRange.RemoveHighlight() ; 523 range.MoveToBookmark( bookmark ) ; 524 525 saveUndoStep( range ) ; 526 range.DeleteContents() ; 527 range.InsertNode( EditorDocument.createTextNode( GetReplaceString() ) ) ; 528 range._UpdateElementInfo() ; 529 530 FindRange = CharacterRange.CreateFromDomRange( range ) ; 531 } 532 else 533 { 534 if ( ! _Find() ) 535 { 536 FindRange && FindRange.RemoveHighlight() ; 537 alert( FCKLang.DlgFindNotFoundMsg ) ; 538 } 539 } 540 } 541 542 function ReplaceAll() 543 { 544 oEditor.FCKUndo.SaveUndoStep() ; 545 var replaceCount = 0 ; 546 547 while ( _Find() ) 548 { 549 var range = FindRange.GetHighlightDomRange() ; 550 var bookmark = range.CreateBookmark() ; 551 FindRange.RemoveHighlight() ; 552 range.MoveToBookmark( bookmark) ; 553 554 range.DeleteContents() ; 555 range.InsertNode( EditorDocument.createTextNode( GetReplaceString() ) ) ; 556 range._UpdateElementInfo() ; 557 558 FindRange = CharacterRange.CreateFromDomRange( range ) ; 559 replaceCount++ ; 560 } 561 if ( replaceCount == 0 ) 562 { 563 FindRange && FindRange.RemoveHighlight() ; 564 alert( FCKLang.DlgFindNotFoundMsg ) ; 565 } 566 dialog.Cancel() ; 567 } 568 569 window.onunload = function() 570 { 571 if ( FindRange ) 572 { 573 FindRange.RemoveHighlight() ; 574 FindRange.ToDomRange().Select() ; 575 } 576 } 577 </script> 578 </head> 579 <body onload="OnLoad()" style="overflow: hidden"> 580 <div id="divFind" style="display: none"> 581 <table cellspacing="3" cellpadding="2" width="100%" border="0"> 582 <tr> 583 <td nowrap="nowrap"> 584 <label for="txtFindFind" fcklang="DlgReplaceFindLbl"> 585 Find what:</label> 586 </td> 587 <td width="100%"> 588 <input id="txtFindFind" onkeyup="btnStat()" oninput="btnStat()" onpaste="btnStatDelayed()" style="width: 100%" tabindex="1" 589 type="text" /> 590 </td> 591 <td> 592 <input id="btnFind" style="width: 80px" disabled="disabled" onclick="Find();" 593 type="button" value="Find" fcklang="DlgFindFindBtn" /> 594 </td> 595 </tr> 596 <tr> 597 <td valign="bottom" colspan="3"> 598 <input id="chkCaseFind" tabindex="3" type="checkbox" /><label for="chkCaseFind" fcklang="DlgReplaceCaseChk">Match 599 case</label> 600 <br /> 601 <input id="chkWordFind" tabindex="4" type="checkbox" /><label for="chkWordFind" fcklang="DlgReplaceWordChk">Match 602 whole word</label> 603 </td> 604 </tr> 605 </table> 606 </div> 607 <div id="divReplace" style="display:none"> 608 <table cellspacing="3" cellpadding="2" width="100%" border="0"> 609 <tr> 610 <td nowrap="nowrap"> 611 <label for="txtFindReplace" fcklang="DlgReplaceFindLbl"> 612 Find what:</label> 613 </td> 614 <td width="100%"> 615 <input id="txtFindReplace" onkeyup="btnStat()" oninput="btnStat()" onpaste="btnStatDelayed()" style="width: 100%" tabindex="1" 616 type="text" /> 617 </td> 618 <td> 619 <input id="btnReplace" style="width: 80px" disabled="disabled" onclick="Replace();" 620 type="button" value="Replace" fcklang="DlgReplaceReplaceBtn" /> 621 </td> 622 </tr> 623 <tr> 624 <td valign="top" nowrap="nowrap"> 625 <label for="txtReplace" fcklang="DlgReplaceReplaceLbl"> 626 Replace with:</label> 627 </td> 628 <td valign="top"> 629 <input id="txtReplace" style="width: 100%" tabindex="2" type="text" /> 630 </td> 631 <td> 632 <input id="btnReplaceAll" style="width: 80px" disabled="disabled" onclick="ReplaceAll()" type="button" 633 value="Replace All" fcklang="DlgReplaceReplAllBtn" /> 634 </td> 635 </tr> 636 <tr> 637 <td valign="bottom" colspan="3"> 638 <input id="chkCaseReplace" tabindex="3" type="checkbox" /><label for="chkCaseReplace" fcklang="DlgReplaceCaseChk">Match 639 case</label> 640 <br /> 641 <input id="chkWordReplace" tabindex="4" type="checkbox" /><label for="chkWordReplace" fcklang="DlgReplaceWordChk">Match 642 whole word</label> 643 </td> 644 </tr> 645 </table> 646 </div> 647 </body> 648 </html>
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Fri Jan 1 13:43:16 2010 | Cross-referenced by PHPXref 0.7 |