| 1925 | jp_milcent | 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>
 |