Index: /CKEditor/branches/prototype/_source/core/event.js
===================================================================
--- /CKEditor/branches/prototype/_source/core/event.js	(revision 2349)
+++ /CKEditor/branches/prototype/_source/core/event.js	(revision 2350)
@@ -189,5 +189,5 @@
 			 *		listener.
 			 * @returns {Boolean|Object} A booloan indicating that the event is to be
-			 *		cancelled, or data returned by one of the listeners.
+			 *		canceled, or data returned by one of the listeners.
 			 * @example
 			 * someObject.on( 'someEvent', function() { ... } );
@@ -210,9 +210,9 @@
 				};
 
-				// Create the function that marks the event as cancelled.
-				var cancelled = false;
+				// Create the function that marks the event as canceled.
+				var canceled = false;
 				var cancelEvent = function()
 				{
-					cancelled = true;
+					canceled = true;
 				};
 
@@ -221,7 +221,12 @@
 					// Get the event entry.
 					var event = this._.events[ eventName ];
-
-					// Reset the stopped and cancelled flags.
-					stopped = cancelled = false;
+					
+					// Save the previous stopped and cancelled states. We may
+					// be nesting fire() calls.
+					var previousStopped = stopped,
+						previousCancelled = canceled;
+
+					// Reset the stopped and canceled flags.
+					stopped = canceled = false;
 
 					if ( event )
@@ -236,11 +241,17 @@
 								data = retData;
 
-							// No further calls is stopped or cancelled.
-							if ( stopped || cancelled )
+							// No further calls is stopped or canceled.
+							if ( stopped || canceled )
 								break;
 						}
 					}
-
-					return cancelled || ( typeof data == 'undefined' ? false : data );
+					
+					var ret = canceled || ( typeof data == 'undefined' ? false : data );
+					
+					// Restore the previous stopped and canceled states.
+					stopped = previousStopped;
+					canceled = previousCancelled;
+
+					return ret;
 				}
 			})(),
@@ -258,5 +269,5 @@
 			 *		listener.
 			 * @returns {Boolean|Object} A booloan indicating that the event is to be
-			 *		cancelled, or data returned by one of the listeners.
+			 *		canceled, or data returned by one of the listeners.
 			 * @example
 			 * someObject.on( 'someEvent', function() { ... } );
Index: /CKEditor/branches/prototype/_source/tests/core/event.html
===================================================================
--- /CKEditor/branches/prototype/_source/tests/core/event.html	(revision 2349)
+++ /CKEditor/branches/prototype/_source/tests/core/event.html	(revision 2350)
@@ -415,4 +415,36 @@
 			assert.areSame( 0, counter, 'number of calls doesn\'t match' );
 		},
+		
+		test_nestedCancel : function()
+		{
+			// Create a testObject and implement CKEDITOR.event on it.
+			var testObject = {};
+			CKEDITOR.event.implementOn( testObject );
+
+			var isCanceledA,
+				isCanceledB,
+				isCanceledC;
+
+			testObject.on( 'A', function( ev )
+				{
+					isCanceledB = testObject.fire( 'B' );
+					isCanceledC = testObject.fire( 'C' );
+				});
+			
+			testObject.on( 'B', function( ev )
+				{
+					ev.cancel();
+				});
+			
+			testObject.on( 'C', function( ev )
+				{
+				});
+			
+			isCanceledA = testObject.fire( 'A' );
+
+			assert.areSame( false, isCanceledA, 'event A must not be canceled' );
+			assert.areSame( true, isCanceledB, 'event B must be canceled' );
+			assert.areSame( false, isCanceledC, 'event C must not be canceled' );
+		},
 
 		name : document.title
