\r
(function()\r
{\r
- // List of elements in which has no way to move editing focus outside.\r
- var nonExitableElementNames = { table:1,pre:1 };\r
-\r
// Matching an empty paragraph at the end of document.\r
- var emptyParagraphRegexp = /(^|<body\b[^>]*>)\s*<(p|div|address|h\d|center)[^>]*>\s*(?:<br[^>]*>| |\u00A0| )?\s*(:?<\/\2>)?\s*(?=$|<\/body>)/gi;\r
+ var emptyParagraphRegexp = /(^|<body\b[^>]*>)\s*<(p|div|address|h\d|center|pre)[^>]*>\s*(?:<br[^>]*>| |\u00A0| )?\s*(:?<\/\2>)?\s*(?=$|<\/body>)/gi;\r
\r
var notWhitespaceEval = CKEDITOR.dom.walker.whitespaces( true );\r
\r
- // Elements that could have empty new line around, including table, pre-formatted block, hr, page-break. (#6554)\r
- function nonExitable( element )\r
+ // Elements that could blink the cursor anchoring beside it, like hr, page-break. (#6554)\r
+ function nonEditable( element )\r
{\r
- return ( element.getName() in nonExitableElementNames )\r
- || element.isBlockBoundary() && CKEDITOR.dtd.$empty[ element.getName() ];\r
+ return element.isBlockBoundary() && CKEDITOR.dtd.$empty[ element.getName() ];\r
}\r
\r
\r
var pathBlock = path.block || path.blockLimit,\r
lastNode = pathBlock && pathBlock.getLast( isNotEmpty );\r
\r
- // In case it's not ended with block element and doesn't have bogus yet. (#7467)\r
+ // Check some specialities of the current path block:\r
+ // 1. It is really displayed as block; (#7221)\r
+ // 2. It doesn't end with one inner block; (#7467)\r
+ // 3. It doesn't have bogus br yet.\r
if ( pathBlock\r
+ && pathBlock.isBlockBoundary()\r
&& !( lastNode && lastNode.type == CKEDITOR.NODE_ELEMENT && lastNode.isBlockBoundary() )\r
&& !pathBlock.is( 'pre' )\r
&& !pathBlock.getBogus() )\r
var element = fixedBlock.getNext( isNotWhitespace );\r
if ( element &&\r
element.type == CKEDITOR.NODE_ELEMENT &&\r
- !nonExitable( element ) )\r
+ !nonEditable( element ) )\r
{\r
range.moveToElementEditStart( element );\r
fixedBlock.remove();\r
element = fixedBlock.getPrevious( isNotWhitespace );\r
if ( element &&\r
element.type == CKEDITOR.NODE_ELEMENT &&\r
- !nonExitable( element ) )\r
+ !nonEditable( element ) )\r
{\r
range.moveToElementEditEnd( element );\r
fixedBlock.remove();\r
evt.cancel();\r
}\r
\r
- // All browsers are incapable to moving cursor out of certain non-exitable\r
- // blocks (e.g. table, list, pre) at the end of document, make this happen by\r
- // place a bogus node there, which would be later removed by dataprocessor.\r
- var walkerRange = new CKEDITOR.dom.range( editor.document ),\r
- walker = new CKEDITOR.dom.walker( walkerRange );\r
- walkerRange.selectNodeContents( body );\r
- walker.evaluator = function( node )\r
- {\r
- return node.type == CKEDITOR.NODE_ELEMENT && ( node.getName() in nonExitableElementNames );\r
- };\r
- walker.guard = function( node, isMoveout )\r
- {\r
- return !( ( node.type == CKEDITOR.NODE_TEXT && isNotWhitespace( node ) ) || isMoveout );\r
- };\r
-\r
- if ( walker.previous() )\r
+ // Browsers are incapable of moving cursor out of certain block elements (e.g. table, div, pre)\r
+ // at the end of document, makes it unable to continue adding content, we have to make this\r
+ // easier by opening an new empty paragraph.\r
+ var testRange = new CKEDITOR.dom.range( editor.document );\r
+ testRange.moveToElementEditEnd( editor.document.getBody() );\r
+ var testPath = new CKEDITOR.dom.elementPath( testRange.startContainer );\r
+ if ( !testPath.blockLimit.is( 'body') )\r
{\r
editor.fire( 'updateSnapshot' );\r
restoreDirty( editor );\r
\r
var paddingBlock;\r
if ( enterMode != CKEDITOR.ENTER_BR )\r
- paddingBlock = body.append( new CKEDITOR.dom.element( enterMode == CKEDITOR.ENTER_P ? 'p' : 'div' ) );\r
+ paddingBlock = body.append( editor.document.createElement( enterMode == CKEDITOR.ENTER_P ? 'p' : 'div' ) );\r
else\r
paddingBlock = body;\r
\r