+++ /dev/null
-/*\r
-Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved.\r
-For licensing, see LICENSE.html or http://ckeditor.com/license\r
-*/\r
-\r
-(function()\r
-{\r
- var isReplace;\r
-\r
- function findEvaluator( node )\r
- {\r
- return node.type == CKEDITOR.NODE_TEXT && node.getLength() > 0 && ( !isReplace || !node.isReadOnly() );\r
- }\r
-\r
- /**\r
- * Elements which break characters been considered as sequence.\r
- */\r
- function nonCharactersBoundary( node )\r
- {\r
- return !( node.type == CKEDITOR.NODE_ELEMENT && node.isBlockBoundary(\r
- CKEDITOR.tools.extend( {}, CKEDITOR.dtd.$empty, CKEDITOR.dtd.$nonEditable ) ) );\r
- }\r
-\r
- /**\r
- * Get the cursor object which represent both current character and it's dom\r
- * position thing.\r
- */\r
- var cursorStep = function()\r
- {\r
- return {\r
- textNode : this.textNode,\r
- offset : this.offset,\r
- character : this.textNode ?\r
- this.textNode.getText().charAt( this.offset ) : null,\r
- hitMatchBoundary : this._.matchBoundary\r
- };\r
- };\r
-\r
- var pages = [ 'find', 'replace' ],\r
- fieldsMapping = [\r
- [ 'txtFindFind', 'txtFindReplace' ],\r
- [ 'txtFindCaseChk', 'txtReplaceCaseChk' ],\r
- [ 'txtFindWordChk', 'txtReplaceWordChk' ],\r
- [ 'txtFindCyclic', 'txtReplaceCyclic' ] ];\r
-\r
- /**\r
- * Synchronize corresponding filed values between 'replace' and 'find' pages.\r
- * @param {String} currentPageId The page id which receive values.\r
- */\r
- function syncFieldsBetweenTabs( currentPageId )\r
- {\r
- var sourceIndex, targetIndex,\r
- sourceField, targetField;\r
-\r
- sourceIndex = currentPageId === 'find' ? 1 : 0;\r
- targetIndex = 1 - sourceIndex;\r
- var i, l = fieldsMapping.length;\r
- for ( i = 0 ; i < l ; i++ )\r
- {\r
- sourceField = this.getContentElement( pages[ sourceIndex ],\r
- fieldsMapping[ i ][ sourceIndex ] );\r
- targetField = this.getContentElement( pages[ targetIndex ],\r
- fieldsMapping[ i ][ targetIndex ] );\r
-\r
- targetField.setValue( sourceField.getValue() );\r
- }\r
- }\r
-\r
- var findDialog = function( editor, startupPage )\r
- {\r
- // Style object for highlights: (#5018)\r
- // 1. Defined as full match style to avoid compromising ordinary text color styles.\r
- // 2. Must be apply onto inner-most text to avoid conflicting with ordinary text color styles visually.\r
- var highlightStyle = new CKEDITOR.style(\r
- CKEDITOR.tools.extend( { attributes : { 'data-cke-highlight': 1 }, fullMatch : 1, ignoreReadonly : 1, childRule : function(){ return 0; } },\r
- editor.config.find_highlight, true ) );\r
-\r
- /**\r
- * Iterator which walk through the specified range char by char. By\r
- * default the walking will not stop at the character boundaries, until\r
- * the end of the range is encountered.\r
- * @param { CKEDITOR.dom.range } range\r
- * @param {Boolean} matchWord Whether the walking will stop at character boundary.\r
- */\r
- var characterWalker = function( range , matchWord )\r
- {\r
- var self = this;\r
- var walker =\r
- new CKEDITOR.dom.walker( range );\r
- walker.guard = matchWord ? nonCharactersBoundary : function( node )\r
- {\r
- !nonCharactersBoundary( node ) && ( self._.matchBoundary = true );\r
- };\r
- walker[ 'evaluator' ] = findEvaluator;\r
- walker.breakOnFalse = 1;\r
-\r
- if ( range.startContainer.type == CKEDITOR.NODE_TEXT )\r
- {\r
- this.textNode = range.startContainer;\r
- this.offset = range.startOffset - 1;\r
- }\r
-\r
- this._ = {\r
- matchWord : matchWord,\r
- walker : walker,\r
- matchBoundary : false\r
- };\r
- };\r
-\r
- characterWalker.prototype = {\r
- next : function()\r
- {\r
- return this.move();\r
- },\r
-\r
- back : function()\r
- {\r
- return this.move( true );\r
- },\r
-\r
- move : function( rtl )\r
- {\r
- var currentTextNode = this.textNode;\r
- // Already at the end of document, no more character available.\r
- if ( currentTextNode === null )\r
- return cursorStep.call( this );\r
-\r
- this._.matchBoundary = false;\r
-\r
- // There are more characters in the text node, step forward.\r
- if ( currentTextNode\r
- && rtl\r
- && this.offset > 0 )\r
- {\r
- this.offset--;\r
- return cursorStep.call( this );\r
- }\r
- else if ( currentTextNode\r
- && this.offset < currentTextNode.getLength() - 1 )\r
- {\r
- this.offset++;\r
- return cursorStep.call( this );\r
- }\r
- else\r
- {\r
- currentTextNode = null;\r
- // At the end of the text node, walking foward for the next.\r
- while ( !currentTextNode )\r
- {\r
- currentTextNode =\r
- this._.walker[ rtl ? 'previous' : 'next' ].call( this._.walker );\r
-\r
- // Stop searching if we're need full word match OR\r
- // already reach document end.\r
- if ( this._.matchWord && !currentTextNode\r
- || this._.walker._.end )\r
- break;\r
- }\r
- // Found a fresh text node.\r
- this.textNode = currentTextNode;\r
- if ( currentTextNode )\r
- this.offset = rtl ? currentTextNode.getLength() - 1 : 0;\r
- else\r
- this.offset = 0;\r
- }\r
-\r
- return cursorStep.call( this );\r
- }\r
-\r
- };\r
-\r
- /**\r
- * A range of cursors which represent a trunk of characters which try to\r
- * match, it has the same length as the pattern string.\r
- */\r
- var characterRange = function( characterWalker, rangeLength )\r
- {\r
- this._ = {\r
- walker : characterWalker,\r
- cursors : [],\r
- rangeLength : rangeLength,\r
- highlightRange : null,\r
- isMatched : 0\r
- };\r
- };\r
-\r
- characterRange.prototype = {\r
- /**\r
- * Translate this range to {@link CKEDITOR.dom.range}\r
- */\r
- toDomRange : function()\r
- {\r
- var range = new CKEDITOR.dom.range( editor.document );\r
- var cursors = this._.cursors;\r
- if ( cursors.length < 1 )\r
- {\r
- var textNode = this._.walker.textNode;\r
- if ( textNode )\r
- range.setStartAfter( textNode );\r
- else\r
- return null;\r
- }\r
- else\r
- {\r
- var first = cursors[0],\r
- last = cursors[ cursors.length - 1 ];\r
-\r
- range.setStart( first.textNode, first.offset );\r
- range.setEnd( last.textNode, last.offset + 1 );\r
- }\r
-\r
- return range;\r
- },\r
- /**\r
- * Reflect the latest changes from dom range.\r
- */\r
- updateFromDomRange : function( domRange )\r
- {\r
- var cursor,\r
- walker = new characterWalker( domRange );\r
- this._.cursors = [];\r
- do\r
- {\r
- cursor = walker.next();\r
- if ( cursor.character )\r
- this._.cursors.push( cursor );\r
- }\r
- while ( cursor.character );\r
- this._.rangeLength = this._.cursors.length;\r
- },\r
-\r
- setMatched : function()\r
- {\r
- this._.isMatched = true;\r
- },\r
-\r
- clearMatched : function()\r
- {\r
- this._.isMatched = false;\r
- },\r
-\r
- isMatched : function()\r
- {\r
- return this._.isMatched;\r
- },\r
-\r
- /**\r
- * Hightlight the current matched chunk of text.\r
- */\r
- highlight : function()\r
- {\r
- // Do not apply if nothing is found.\r
- if ( this._.cursors.length < 1 )\r
- return;\r
-\r
- // Remove the previous highlight if there's one.\r
- if ( this._.highlightRange )\r
- this.removeHighlight();\r
-\r
- // Apply the highlight.\r
- var range = this.toDomRange(),\r
- bookmark = range.createBookmark();\r
- highlightStyle.applyToRange( range );\r
- range.moveToBookmark( bookmark );\r
- this._.highlightRange = range;\r
-\r
- // Scroll the editor to the highlighted area.\r
- var element = range.startContainer;\r
- if ( element.type != CKEDITOR.NODE_ELEMENT )\r
- element = element.getParent();\r
- element.scrollIntoView();\r
-\r
- // Update the character cursors.\r
- this.updateFromDomRange( range );\r
- },\r
-\r
- /**\r
- * Remove highlighted find result.\r
- */\r
- removeHighlight : function()\r
- {\r
- if ( !this._.highlightRange )\r
- return;\r
-\r
- var bookmark = this._.highlightRange.createBookmark();\r
- highlightStyle.removeFromRange( this._.highlightRange );\r
- this._.highlightRange.moveToBookmark( bookmark );\r
- this.updateFromDomRange( this._.highlightRange );\r
- this._.highlightRange = null;\r
- },\r
-\r
- isReadOnly : function()\r
- {\r
- if ( !this._.highlightRange )\r
- return 0;\r
-\r
- return this._.highlightRange.startContainer.isReadOnly();\r
- },\r
-\r
- moveBack : function()\r
- {\r
- var retval = this._.walker.back(),\r
- cursors = this._.cursors;\r
-\r
- if ( retval.hitMatchBoundary )\r
- this._.cursors = cursors = [];\r
-\r
- cursors.unshift( retval );\r
- if ( cursors.length > this._.rangeLength )\r
- cursors.pop();\r
-\r
- return retval;\r
- },\r
-\r
- moveNext : function()\r
- {\r
- var retval = this._.walker.next(),\r
- cursors = this._.cursors;\r
-\r
- // Clear the cursors queue if we've crossed a match boundary.\r
- if ( retval.hitMatchBoundary )\r
- this._.cursors = cursors = [];\r
-\r
- cursors.push( retval );\r
- if ( cursors.length > this._.rangeLength )\r
- cursors.shift();\r
-\r
- return retval;\r
- },\r
-\r
- getEndCharacter : function()\r
- {\r
- var cursors = this._.cursors;\r
- if ( cursors.length < 1 )\r
- return null;\r
-\r
- return cursors[ cursors.length - 1 ].character;\r
- },\r
-\r
- getNextCharacterRange : function( maxLength )\r
- {\r
- var lastCursor,\r
- nextRangeWalker,\r
- cursors = this._.cursors;\r
-\r
- if ( ( lastCursor = cursors[ cursors.length - 1 ] ) && lastCursor.textNode )\r
- nextRangeWalker = new characterWalker( getRangeAfterCursor( lastCursor ) );\r
- // In case it's an empty range (no cursors), figure out next range from walker (#4951).\r
- else\r
- nextRangeWalker = this._.walker;\r
-\r
- return new characterRange( nextRangeWalker, maxLength );\r
- },\r
-\r
- getCursors : function()\r
- {\r
- return this._.cursors;\r
- }\r
- };\r
-\r
-\r
- // The remaining document range after the character cursor.\r
- function getRangeAfterCursor( cursor , inclusive )\r
- {\r
- var range = new CKEDITOR.dom.range();\r
- range.setStart( cursor.textNode,\r
- ( inclusive ? cursor.offset : cursor.offset + 1 ) );\r
- range.setEndAt( editor.document.getBody(),\r
- CKEDITOR.POSITION_BEFORE_END );\r
- return range;\r
- }\r
-\r
- // The document range before the character cursor.\r
- function getRangeBeforeCursor( cursor )\r
- {\r
- var range = new CKEDITOR.dom.range();\r
- range.setStartAt( editor.document.getBody(),\r
- CKEDITOR.POSITION_AFTER_START );\r
- range.setEnd( cursor.textNode, cursor.offset );\r
- return range;\r
- }\r
-\r
- var KMP_NOMATCH = 0,\r
- KMP_ADVANCED = 1,\r
- KMP_MATCHED = 2;\r
- /**\r
- * Examination the occurrence of a word which implement KMP algorithm.\r
- */\r
- var kmpMatcher = function( pattern, ignoreCase )\r
- {\r
- var overlap = [ -1 ];\r
- if ( ignoreCase )\r
- pattern = pattern.toLowerCase();\r
- for ( var i = 0 ; i < pattern.length ; i++ )\r
- {\r
- overlap.push( overlap[i] + 1 );\r
- while ( overlap[ i + 1 ] > 0\r
- && pattern.charAt( i ) != pattern\r
- .charAt( overlap[ i + 1 ] - 1 ) )\r
- overlap[ i + 1 ] = overlap[ overlap[ i + 1 ] - 1 ] + 1;\r
- }\r
-\r
- this._ = {\r
- overlap : overlap,\r
- state : 0,\r
- ignoreCase : !!ignoreCase,\r
- pattern : pattern\r
- };\r
- };\r
-\r
- kmpMatcher.prototype =\r
- {\r
- feedCharacter : function( c )\r
- {\r
- if ( this._.ignoreCase )\r
- c = c.toLowerCase();\r
-\r
- while ( true )\r
- {\r
- if ( c == this._.pattern.charAt( this._.state ) )\r
- {\r
- this._.state++;\r
- if ( this._.state == this._.pattern.length )\r
- {\r
- this._.state = 0;\r
- return KMP_MATCHED;\r
- }\r
- return KMP_ADVANCED;\r
- }\r
- else if ( !this._.state )\r
- return KMP_NOMATCH;\r
- else\r
- this._.state = this._.overlap[ this._.state ];\r
- }\r
-\r
- return null;\r
- },\r
-\r
- reset : function()\r
- {\r
- this._.state = 0;\r
- }\r
- };\r
-\r
- var wordSeparatorRegex =\r
- /[.,"'?!;: \u0085\u00a0\u1680\u280e\u2028\u2029\u202f\u205f\u3000]/;\r
-\r
- var isWordSeparator = function( c )\r
- {\r
- if ( !c )\r
- return true;\r
- var code = c.charCodeAt( 0 );\r
- return ( code >= 9 && code <= 0xd )\r
- || ( code >= 0x2000 && code <= 0x200a )\r
- || wordSeparatorRegex.test( c );\r
- };\r
-\r
- var finder = {\r
- searchRange : null,\r
- matchRange : null,\r
- find : function( pattern, matchCase, matchWord, matchCyclic, highlightMatched, cyclicRerun )\r
- {\r
- if ( !this.matchRange )\r
- this.matchRange =\r
- new characterRange(\r
- new characterWalker( this.searchRange ),\r
- pattern.length );\r
- else\r
- {\r
- this.matchRange.removeHighlight();\r
- this.matchRange = this.matchRange.getNextCharacterRange( pattern.length );\r
- }\r
-\r
- var matcher = new kmpMatcher( pattern, !matchCase ),\r
- matchState = KMP_NOMATCH,\r
- character = '%';\r
-\r
- while ( character !== null )\r
- {\r
- this.matchRange.moveNext();\r
- while ( ( character = this.matchRange.getEndCharacter() ) )\r
- {\r
- matchState = matcher.feedCharacter( character );\r
- if ( matchState == KMP_MATCHED )\r
- break;\r
- if ( this.matchRange.moveNext().hitMatchBoundary )\r
- matcher.reset();\r
- }\r
-\r
- if ( matchState == KMP_MATCHED )\r
- {\r
- if ( matchWord )\r
- {\r
- var cursors = this.matchRange.getCursors(),\r
- tail = cursors[ cursors.length - 1 ],\r
- head = cursors[ 0 ];\r
-\r
- var rangeBefore = getRangeBeforeCursor( head ),\r
- rangeAfter = getRangeAfterCursor( tail );\r
-\r
- // The word boundary checks requires to trim the text nodes. (#9036)\r
- rangeBefore.trim();\r
- rangeAfter.trim();\r
-\r
- var headWalker = new characterWalker( rangeBefore, true ),\r
- tailWalker = new characterWalker( rangeAfter, true );\r
-\r
- if ( ! ( isWordSeparator( headWalker.back().character )\r
- && isWordSeparator( tailWalker.next().character ) ) )\r
- continue;\r
- }\r
- this.matchRange.setMatched();\r
- if ( highlightMatched !== false )\r
- this.matchRange.highlight();\r
- return true;\r
- }\r
- }\r
-\r
- this.matchRange.clearMatched();\r
- this.matchRange.removeHighlight();\r
- // Clear current session and restart with the default search\r
- // range.\r
- // Re-run the finding once for cyclic.(#3517)\r
- if ( matchCyclic && !cyclicRerun )\r
- {\r
- this.searchRange = getSearchRange( 1 );\r
- this.matchRange = null;\r
- return arguments.callee.apply( this,\r
- Array.prototype.slice.call( arguments ).concat( [ true ] ) );\r
- }\r
-\r
- return false;\r
- },\r
-\r
- /**\r
- * Record how much replacement occurred toward one replacing.\r
- */\r
- replaceCounter : 0,\r
-\r
- replace : function( dialog, pattern, newString, matchCase, matchWord,\r
- matchCyclic , isReplaceAll )\r
- {\r
- isReplace = 1;\r
-\r
- // Successiveness of current replace/find.\r
- var result = 0;\r
-\r
- // 1. Perform the replace when there's already a match here.\r
- // 2. Otherwise perform the find but don't replace it immediately.\r
- if ( this.matchRange && this.matchRange.isMatched()\r
- && !this.matchRange._.isReplaced && !this.matchRange.isReadOnly() )\r
- {\r
- // Turn off highlight for a while when saving snapshots.\r
- this.matchRange.removeHighlight();\r
- var domRange = this.matchRange.toDomRange();\r
- var text = editor.document.createText( newString );\r
- if ( !isReplaceAll )\r
- {\r
- // Save undo snaps before and after the replacement.\r
- var selection = editor.getSelection();\r
- selection.selectRanges( [ domRange ] );\r
- editor.fire( 'saveSnapshot' );\r
- }\r
- domRange.deleteContents();\r
- domRange.insertNode( text );\r
- if ( !isReplaceAll )\r
- {\r
- selection.selectRanges( [ domRange ] );\r
- editor.fire( 'saveSnapshot' );\r
- }\r
- this.matchRange.updateFromDomRange( domRange );\r
- if ( !isReplaceAll )\r
- this.matchRange.highlight();\r
- this.matchRange._.isReplaced = true;\r
- this.replaceCounter++;\r
- result = 1;\r
- }\r
- else\r
- result = this.find( pattern, matchCase, matchWord, matchCyclic, !isReplaceAll );\r
-\r
- isReplace = 0;\r
-\r
- return result;\r
- }\r
- };\r
-\r
- /**\r
- * The range in which find/replace happened, receive from user\r
- * selection prior.\r
- */\r
- function getSearchRange( isDefault )\r
- {\r
- var searchRange,\r
- sel = editor.getSelection(),\r
- body = editor.document.getBody();\r
- if ( sel && !isDefault )\r
- {\r
- searchRange = sel.getRanges()[ 0 ].clone();\r
- searchRange.collapse( true );\r
- }\r
- else\r
- {\r
- searchRange = new CKEDITOR.dom.range();\r
- searchRange.setStartAt( body, CKEDITOR.POSITION_AFTER_START );\r
- }\r
- searchRange.setEndAt( body, CKEDITOR.POSITION_BEFORE_END );\r
- return searchRange;\r
- }\r
-\r
- var lang = editor.lang.findAndReplace;\r
- return {\r
- title : lang.title,\r
- resizable : CKEDITOR.DIALOG_RESIZE_NONE,\r
- minWidth : 350,\r
- minHeight : 170,\r
- buttons : [ CKEDITOR.dialog.cancelButton ], // Cancel button only.\r
- contents : [\r
- {\r
- id : 'find',\r
- label : lang.find,\r
- title : lang.find,\r
- accessKey : '',\r
- elements : [\r
- {\r
- type : 'hbox',\r
- widths : [ '230px', '90px' ],\r
- children :\r
- [\r
- {\r
- type : 'text',\r
- id : 'txtFindFind',\r
- label : lang.findWhat,\r
- isChanged : false,\r
- labelLayout : 'horizontal',\r
- accessKey : 'F'\r
- },\r
- {\r
- type : 'button',\r
- id : 'btnFind',\r
- align : 'left',\r
- style : 'width:100%',\r
- label : lang.find,\r
- onClick : function()\r
- {\r
- var dialog = this.getDialog();\r
- if ( !finder.find( dialog.getValueOf( 'find', 'txtFindFind' ),\r
- dialog.getValueOf( 'find', 'txtFindCaseChk' ),\r
- dialog.getValueOf( 'find', 'txtFindWordChk' ),\r
- dialog.getValueOf( 'find', 'txtFindCyclic' ) ) )\r
- alert( lang\r
- .notFoundMsg );\r
- }\r
- }\r
- ]\r
- },\r
- {\r
- type : 'fieldset',\r
- label : CKEDITOR.tools.htmlEncode( lang.findOptions ),\r
- style : 'margin-top:29px',\r
- children :\r
- [\r
- {\r
- type : 'vbox',\r
- padding : 0,\r
- children :\r
- [\r
- {\r
- type : 'checkbox',\r
- id : 'txtFindCaseChk',\r
- isChanged : false,\r
- label : lang.matchCase\r
- },\r
- {\r
- type : 'checkbox',\r
- id : 'txtFindWordChk',\r
- isChanged : false,\r
- label : lang.matchWord\r
- },\r
- {\r
- type : 'checkbox',\r
- id : 'txtFindCyclic',\r
- isChanged : false,\r
- 'default' : true,\r
- label : lang.matchCyclic\r
- }\r
- ]\r
- }\r
- ]\r
- }\r
- ]\r
- },\r
- {\r
- id : 'replace',\r
- label : lang.replace,\r
- accessKey : 'M',\r
- elements : [\r
- {\r
- type : 'hbox',\r
- widths : [ '230px', '90px' ],\r
- children :\r
- [\r
- {\r
- type : 'text',\r
- id : 'txtFindReplace',\r
- label : lang.findWhat,\r
- isChanged : false,\r
- labelLayout : 'horizontal',\r
- accessKey : 'F'\r
- },\r
- {\r
- type : 'button',\r
- id : 'btnFindReplace',\r
- align : 'left',\r
- style : 'width:100%',\r
- label : lang.replace,\r
- onClick : function()\r
- {\r
- var dialog = this.getDialog();\r
- if ( !finder.replace( dialog,\r
- dialog.getValueOf( 'replace', 'txtFindReplace' ),\r
- dialog.getValueOf( 'replace', 'txtReplace' ),\r
- dialog.getValueOf( 'replace', 'txtReplaceCaseChk' ),\r
- dialog.getValueOf( 'replace', 'txtReplaceWordChk' ),\r
- dialog.getValueOf( 'replace', 'txtReplaceCyclic' ) ) )\r
- alert( lang\r
- .notFoundMsg );\r
- }\r
- }\r
- ]\r
- },\r
- {\r
- type : 'hbox',\r
- widths : [ '230px', '90px' ],\r
- children :\r
- [\r
- {\r
- type : 'text',\r
- id : 'txtReplace',\r
- label : lang.replaceWith,\r
- isChanged : false,\r
- labelLayout : 'horizontal',\r
- accessKey : 'R'\r
- },\r
- {\r
- type : 'button',\r
- id : 'btnReplaceAll',\r
- align : 'left',\r
- style : 'width:100%',\r
- label : lang.replaceAll,\r
- isChanged : false,\r
- onClick : function()\r
- {\r
- var dialog = this.getDialog();\r
- var replaceNums;\r
-\r
- finder.replaceCounter = 0;\r
-\r
- // Scope to full document.\r
- finder.searchRange = getSearchRange( 1 );\r
- if ( finder.matchRange )\r
- {\r
- finder.matchRange.removeHighlight();\r
- finder.matchRange = null;\r
- }\r
- editor.fire( 'saveSnapshot' );\r
- while ( finder.replace( dialog,\r
- dialog.getValueOf( 'replace', 'txtFindReplace' ),\r
- dialog.getValueOf( 'replace', 'txtReplace' ),\r
- dialog.getValueOf( 'replace', 'txtReplaceCaseChk' ),\r
- dialog.getValueOf( 'replace', 'txtReplaceWordChk' ),\r
- false, true ) )\r
- { /*jsl:pass*/ }\r
-\r
- if ( finder.replaceCounter )\r
- {\r
- alert( lang.replaceSuccessMsg.replace( /%1/, finder.replaceCounter ) );\r
- editor.fire( 'saveSnapshot' );\r
- }\r
- else\r
- alert( lang.notFoundMsg );\r
- }\r
- }\r
- ]\r
- },\r
- {\r
- type : 'fieldset',\r
- label : CKEDITOR.tools.htmlEncode( lang.findOptions ),\r
- children :\r
- [\r
- {\r
- type : 'vbox',\r
- padding : 0,\r
- children :\r
- [\r
- {\r
- type : 'checkbox',\r
- id : 'txtReplaceCaseChk',\r
- isChanged : false,\r
- label : lang.matchCase\r
- },\r
- {\r
- type : 'checkbox',\r
- id : 'txtReplaceWordChk',\r
- isChanged : false,\r
- label : lang.matchWord\r
- },\r
- {\r
- type : 'checkbox',\r
- id : 'txtReplaceCyclic',\r
- isChanged : false,\r
- 'default' : true,\r
- label : lang.matchCyclic\r
- }\r
- ]\r
- }\r
- ]\r
- }\r
- ]\r
- }\r
- ],\r
- onLoad : function()\r
- {\r
- var dialog = this;\r
-\r
- // Keep track of the current pattern field in use.\r
- var patternField, wholeWordChkField;\r
-\r
- // Ignore initial page select on dialog show\r
- var isUserSelect = 0;\r
- this.on( 'hide', function()\r
- {\r
- isUserSelect = 0;\r
- });\r
- this.on( 'show', function()\r
- {\r
- isUserSelect = 1;\r
- });\r
-\r
- this.selectPage = CKEDITOR.tools.override( this.selectPage, function( originalFunc )\r
- {\r
- return function( pageId )\r
- {\r
- originalFunc.call( dialog, pageId );\r
-\r
- var currPage = dialog._.tabs[ pageId ];\r
- var patternFieldInput, patternFieldId, wholeWordChkFieldId;\r
- patternFieldId = pageId === 'find' ? 'txtFindFind' : 'txtFindReplace';\r
- wholeWordChkFieldId = pageId === 'find' ? 'txtFindWordChk' : 'txtReplaceWordChk';\r
-\r
- patternField = dialog.getContentElement( pageId,\r
- patternFieldId );\r
- wholeWordChkField = dialog.getContentElement( pageId,\r
- wholeWordChkFieldId );\r
-\r
- // Prepare for check pattern text filed 'keyup' event\r
- if ( !currPage.initialized )\r
- {\r
- patternFieldInput = CKEDITOR.document\r
- .getById( patternField._.inputId );\r
- currPage.initialized = true;\r
- }\r
-\r
- // Synchronize fields on tab switch.\r
- if ( isUserSelect )\r
- syncFieldsBetweenTabs.call( this, pageId );\r
- };\r
- } );\r
-\r
- },\r
- onShow : function()\r
- {\r
- // Establish initial searching start position.\r
- finder.searchRange = getSearchRange();\r
-\r
- // Fill in the find field with selected text.\r
- var selectedText = this.getParentEditor().getSelection().getSelectedText(),\r
- patternFieldId = ( startupPage == 'find' ? 'txtFindFind' : 'txtFindReplace' );\r
-\r
- var field = this.getContentElement( startupPage, patternFieldId );\r
- field.setValue( selectedText );\r
- field.select();\r
-\r
- this.selectPage( startupPage );\r
-\r
- this[ ( startupPage == 'find' && this._.editor.readOnly? 'hide' : 'show' ) + 'Page' ]( 'replace');\r
- },\r
- onHide : function()\r
- {\r
- var range;\r
- if ( finder.matchRange && finder.matchRange.isMatched() )\r
- {\r
- finder.matchRange.removeHighlight();\r
- editor.focus();\r
-\r
- range = finder.matchRange.toDomRange();\r
- if ( range )\r
- editor.getSelection().selectRanges( [ range ] );\r
- }\r
-\r
- // Clear current session before dialog close\r
- delete finder.matchRange;\r
- },\r
- onFocus : function()\r
- {\r
- if ( startupPage == 'replace' )\r
- return this.getContentElement( 'replace', 'txtFindReplace' );\r
- else\r
- return this.getContentElement( 'find', 'txtFindFind' );\r
- }\r
- };\r
- };\r
-\r
- CKEDITOR.dialog.add( 'find', function( editor )\r
- {\r
- return findDialog( editor, 'find' );\r
- });\r
-\r
- CKEDITOR.dialog.add( 'replace', function( editor )\r
- {\r
- return findDialog( editor, 'replace' );\r
- });\r
-})();\r