\r
(function()\r
{\r
- function nonEmptyText( node )\r
+ var isReplace;\r
+\r
+ function findEvaluator( node )\r
{\r
- return ( node.type == CKEDITOR.NODE_TEXT && node.getLength() > 0 );\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
+ function nonCharactersBoundary( node )\r
{\r
return !( node.type == CKEDITOR.NODE_ELEMENT && node.isBlockBoundary(\r
CKEDITOR.tools.extend( {}, CKEDITOR.dtd.$empty, CKEDITOR.dtd.$nonEditable ) ) );\r
var walker =\r
new CKEDITOR.dom.walker( range );\r
walker.guard = matchWord ? nonCharactersBoundary : null;\r
- walker[ 'evaluator' ] = nonEmptyText;\r
+ walker[ 'evaluator' ] = findEvaluator;\r
walker.breakOnFalse = true;\r
\r
this._ = {\r
this.removeHighlight();\r
\r
// Apply the highlight.\r
- var range = this.toDomRange();\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
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
nextRangeWalker,\r
cursors = this._.cursors;\r
\r
- if ( ( lastCursor = cursors[ cursors.length - 1 ] ) )\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
replace : function( dialog, pattern, newString, matchCase, matchWord,\r
matchCyclic , isReplaceAll )\r
{\r
+ isReplace = 1;\r
+\r
// Successiveness of current replace/find.\r
var result = false;\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 )\r
+ && !this.matchRange._.isReplaced && !this.matchRange.isReadOnly() )\r
{\r
// Turn off highlight for a while when saving snapshots.\r
this.matchRange.removeHighlight();\r
else\r
result = this.find( pattern, matchCase, matchWord, matchCyclic, !isReplaceAll );\r
\r
+ isReplace = 0;\r
+\r
return result;\r
}\r
};\r