Index: /CKEditor/branches/prototype/_source/core/config.js
===================================================================
--- /CKEditor/branches/prototype/_source/core/config.js	(revision 2829)
+++ /CKEditor/branches/prototype/_source/core/config.js	(revision 2830)
@@ -162,5 +162,5 @@
 	 * config.plugins = 'elementspath,toolbar,wysiwygarea';
 	 */
-	plugins : 'basicstyles,button,dialog,elementspath,horizontalrule,htmldataprocessor,keystrokes,removeformat,domwalker,smiley,link,sourcearea,tab,toolbar,wysiwygarea,forms,image,find,table,specialchar,flash',
+	plugins : 'basicstyles,button,dialog,elementspath,horizontalrule,htmldataprocessor,keystrokes,removeformat,smiley,link,sourcearea,tab,toolbar,wysiwygarea,forms,image,find,table,specialchar,flash',
 
 	/**
Index: /CKEditor/branches/prototype/_source/core/dom/domwalker.js
===================================================================
--- /CKEditor/branches/prototype/_source/core/dom/domwalker.js	(revision 2830)
+++ /CKEditor/branches/prototype/_source/core/dom/domwalker.js	(revision 2830)
@@ -0,0 +1,238 @@
+/*
+ * CKEditor - The text editor for Internet - http://ckeditor.com
+ * Copyright (C) 2003-2008 Frederico Caldeira Knabben
+ *
+ * == BEGIN LICENSE ==
+ *
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ *
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ *
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ *
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ *
+ * == END LICENSE ==
+ */
+
+(function()
+{
+	var fireDomWalkerEvent = function( transistionType, fromNode, toNode )
+		{
+			var eventData = { from : fromNode, to : toNode, type : transistionType };
+			this.fire( transistionType, eventData );
+			this._.actionEvents.push( eventData );
+		};
+
+	CKEDITOR.domWalker = function( node )
+	{
+		if ( arguments.length < 1 )
+			return;
+
+		this._ = { currentNode : node, actionEvents : [], stopFlag : false };
+		CKEDITOR.event.implementOn( this );
+	};
+
+	CKEDITOR.domWalker.prototype = {
+		next : (function()
+		{
+			var dfsStepForward = function()
+			{
+				var current = this._.currentNode, next;
+
+				if ( !current )
+					return null;
+
+				if ( current.getChildCount() > 0 )
+				{
+					next = current.getChild( 0 );
+					fireDomWalkerEvent.call( this, 'down', current, next );
+					return next;
+				}
+				else if ( current.getNext() )
+				{
+					next = current.getNext();
+					fireDomWalkerEvent.call( this, 'sibling', current, next );
+					return next;
+				}
+				else
+				{
+					var ancestor = current.getParent();
+					fireDomWalkerEvent.call( this, 'up', current, ancestor );
+
+					while ( ancestor )
+					{
+						if ( ancestor.getNext() )
+						{
+							next = ancestor.getNext();
+							fireDomWalkerEvent.call( this, 'sibling', ancestor, next );
+							return next;
+						}
+						else
+						{
+							next = ancestor.getParent();
+							fireDomWalkerEvent.call( this, 'up', ancestor, next );
+							ancestor = next;
+						}
+					}
+				}
+				return null;
+			};
+
+			return function()
+			{
+				this._.actionEvents = [];
+				return {
+					node : ( this._.currentNode = dfsStepForward.apply( this ) ),
+					events : this._.actionEvents
+				};
+			};
+		})(),
+
+		back : (function()
+		{
+			var dfsStepBackward = function()
+			{
+				var current = this._.currentNode, next;
+
+				if ( !current )
+					return null;
+
+				if ( current.getPrevious() )
+				{
+					var lastChild = current.getPrevious();
+					fireDomWalkerEvent.call( this, 'sibling', current, lastChild );
+					while ( lastChild.getChildCount() > 0 )
+					{
+						next = lastChild.getChild( lastChild.getChildCount() - 1 );
+						fireDomWalkerEvent.call( this, 'down', lastChild, next );
+						lastChild = next;
+					}
+					return lastChild;
+				}
+				else
+				{
+					next = current.getParent();
+					fireDomWalkerEvent.call( this, 'up', current, next );
+					return next;
+				}
+				return null;
+			};
+
+			return function()
+			{
+				this._.actionEvents = [];
+				return {
+					node : ( this._.currentNode = dfsStepBackward.apply( this ) ),
+					events : this._.actionEvents
+				};
+			};
+		})(),
+
+		forward : function( guardFunc )
+		{
+			var retval;
+			this._.stopFlag = false;
+
+			// The default behavior is top stop once the end of document is reached.
+			guardFunc = guardFunc || function( evt ) {};
+
+			this.on( 'sibling', guardFunc );
+			this.on( 'up', guardFunc );
+			this.on( 'down', guardFunc );
+			while( ( !retval || retval.node ) && !this._.stopFlag )
+			{
+				retval = this.next();
+				this.fire( 'step', retval );
+			}
+			this.removeListener( 'sibling', guardFunc );
+			this.removeListener( 'up', guardFunc );
+			this.removeListener( 'down', guardFunc );
+			return retval;
+		},
+
+		reverse : function( guardFunc )
+		{
+			var retval;
+			this._.stopFlag = false;
+
+			// The default behavior is top stop once the start of document is reached.
+			guardFunc = guardFunc || function( evt ) {};
+
+			this.on( 'sibling', guardFunc );
+			this.on( 'up', guardFunc );
+			this.on( 'down', guardFunc );
+			while( ( !retval || retval.node ) && !this._.stopFlag )
+			{
+				retval = this.back();
+				this.fire( 'step', retval );
+			}
+			this.removeListener( 'sibling', guardFunc );
+			this.removeListener( 'up', guardFunc );
+			this.removeListener( 'down', guardFunc );
+			return retval;
+		},
+
+		stop : function()
+		{
+			this._.stopFlag = true;
+			return this;
+		},
+
+		stopped : function()
+		{
+			return this._.stopFlag;
+		},
+
+		setNode : function( node )
+		{
+			this._.currentNode = node;
+			return this;
+		}
+	};
+
+	CKEDITOR.domWalker.blockBoundary = function( customNodeNames )
+	{
+		return function( evt )
+		{
+			/*
+			 * Anything whose display computed style is block, list-item, table,
+			 * table-row-group, table-header-group, table-footer-group, table-row,
+			 * table-column-group, table-column, table-cell, table-caption, or whose node
+			 * name is hr, br (when enterMode is br only) is a block boundary.
+			 */
+			var displayMatches = { block : 1, 'list-item' : 1, table : 1, 'table-row-group' : 1, 'table-header-group' : 1,
+				'table-footer-group' : 1, 'table-row' : 1, 'table-column-group' : 1, 'table-column' : 1, 'table-cell' : 1,
+				'table-caption' : 1 },
+				nodeNameMatches = CKEDITOR.tools.extend( { hr : 1 }, customNodeNames || {} ),
+				to = evt.data.to,
+				from = evt.data.from;
+			if ( to && to.type == CKEDITOR.NODE_ELEMENT )
+			{
+				if ( displayMatches[ to.getComputedStyle( 'display' ) ] || nodeNameMatches[ to.getName() ] )
+				{
+					evt.stop();
+					this.stop();
+					return;
+				}
+			}
+			if ( ( evt.data.type == 'up' || evt.data.type == 'sibling' ) && from && from.type == CKEDITOR.NODE_ELEMENT )
+			{
+				if ( displayMatches[ from.getComputedStyle( 'display' ) ] || nodeNameMatches[ from.getName() ] )
+				{
+					evt.stop();
+					this.stop();
+				}
+			}
+		};
+	};
+
+	CKEDITOR.domWalker.listItemBoundary = function()
+	{
+		return CKEDITOR.domWalker.blockBoundary( { br : 1 } );
+	};
+})();
Index: /CKEditor/branches/prototype/_source/core/loader.js
===================================================================
--- /CKEditor/branches/prototype/_source/core/loader.js	(revision 2829)
+++ /CKEditor/branches/prototype/_source/core/loader.js	(revision 2830)
@@ -56,5 +56,6 @@
 			'core/dom/nodelist'		: [ 'core/dom/node' ],
 			'core/dom/domobject'	: [ 'core/dom/event' ],
-			'core/dom/range'		: [ 'core/dom/document', 'core/dom/documentFragment', 'core/dom/element' ],
+			'core/dom/domwalker'	: [ 'core/dom/node', 'core/dom/element', 'core/dom/document' ],
+			'core/dom/range'		: [ 'core/dom/document', 'core/dom/documentFragment', 'core/dom/element', 'core/dom/domwalker' ],
 			'core/dom/text'			: [ 'core/dom/node', 'core/dom/domobject' ],
 			'core/dom/window'		: [ 'core/dom/domobject' ],
