Index: _source/plugins/enterkey/plugin.js
===================================================================
--- _source/plugins/enterkey/plugin.js (revision 3978)
+++ _source/plugins/enterkey/plugin.js Tue Nov 17 02:31:38 CST 2009
@@ -101,11 +101,12 @@
if ( !isStartOfBlock && !isEndOfBlock )
{
// If the next block is an
with another list tree as the first
- // child, we'll need to append a placeholder or the list item
+ // child, we'll need to append a filler (
/NBSP) or the list item
// wouldn't be editable. (#1420)
- if ( nextBlock.is( 'li' ) && ( node = nextBlock.getFirst() )
+ if ( nextBlock.is( 'li' )
+ && ( node = nextBlock.getFirst( CKEDITOR.dom.walker.invisible( true ) ) )
- && node.is && node.is( 'ul', 'ol') )
+ && node.is && node.is( 'ul', 'ol' ) )
- nextBlock.insertBefore( doc.createText( '\xa0' ), node );
+ ( CKEDITOR.env.ie ? doc.createText( '\xa0') : doc.createElement( 'br' ) ).insertBefore( node );
// Move the selection to the end block.
if ( nextBlock )
Index: _source/core/dom/element.js
===================================================================
--- _source/core/dom/element.js (revision 4196)
+++ _source/core/dom/element.js Tue Nov 17 01:32:20 CST 2009
@@ -627,6 +627,7 @@
/**
* Gets the first child node of this element.
+ * @param {Function} evaluator Filtering the result node.
* @returns {CKEDITOR.dom.node} The first child node or null if not
* available.
* @example
@@ -634,10 +635,14 @@
* var first = element.getFirst();
* alert( first.getName() ); // "b"
*/
- getFirst : function()
+ getFirst : function( evaluator )
{
- var $ = this.$.firstChild;
- return $ ? new CKEDITOR.dom.node( $ ) : null;
+ var first = this.$.firstChild,
+ retval = first && new CKEDITOR.dom.node( first );
+ if ( retval && evaluator && !evaluator( retval ) )
+ retval = retval.getNext( evaluator );
+
+ return retval;
},
/**
Index: _source/core/dom/walker.js
===================================================================
--- _source/core/dom/walker.js (revision 4034)
+++ _source/core/dom/walker.js Tue Nov 17 01:32:20 CST 2009
@@ -408,4 +408,24 @@
return isReject ^ isWhitespace;
};
};
+
+ /**
+ * Whether the node is invisible in wysiwyg mode.
+ * @param isReject
+ */
+ CKEDITOR.dom.walker.invisible = function( isReject )
+ {
+ var whitespace = CKEDITOR.dom.walker.whitespaces();
+ return function( node )
+ {
+ // Nodes that take no spaces in wysiwyg:
+ // 1. White-spaces but not including NBSP;
+ // 2. Empty inline elements, e.g. we're checking here 'offsetHeight'
+ // instead of width for properly excluding all sorts of empty paragraph, e.g.
.
+ var isInvisible = whitespace( node )
+ || !node.$.offsetHeight;
+ return isReject ^ isInvisible;
+ };
+ };
+
})();
Index: _source/plugins/htmldataprocessor/plugin.js
===================================================================
--- _source/plugins/htmldataprocessor/plugin.js (revision 4453)
+++ _source/plugins/htmldataprocessor/plugin.js Tue Nov 17 02:34:56 CST 2009
@@ -45,6 +45,20 @@
return !lastChild || lastChild.type == CKEDITOR.NODE_ELEMENT && lastChild.name == 'br';
}
+ function extendNestedListForDisplay( list )
+ {
+ var children = list.children,
+ firstChild = children && children[ 0 ],
+ secondChild = children && children[ 1 ];
+
+ if( firstChild &&
+ firstChild.type == CKEDITOR.NODE_TEXT
+ && tailNbspRegex.test( firstChild.value )
+ && secondChild && secondChild.type == CKEDITOR.NODE_ELEMENT
+ && secondChild.name in CKEDITOR.dtd.$list )
+ children[ 0 ] = new CKEDITOR.htmlParser.element( 'br', {} );
+ }
+
function extendBlockForDisplay( block )
{
trimFillers( block, true );
@@ -66,6 +80,19 @@
block.add( new CKEDITOR.htmlParser.text( '\xa0' ) );
}
+ function extendNestedListForOutput( list )
+ {
+ var children = list.children,
+ firstChild = children && children[ 0 ],
+ secondChild = children && children[ 1 ];
+
+ if( firstChild && firstChild.type == CKEDITOR.NODE_ELEMENT
+ && firstChild.name == 'br'
+ && secondChild && secondChild.type == CKEDITOR.NODE_ELEMENT
+ && secondChild.name in CKEDITOR.dtd.$list )
+ children[ 0 ] = new CKEDITOR.htmlParser.text( '\xa0' );
+ }
+
var dtd = CKEDITOR.dtd;
// Find out the list of block-like tags that can contain
.
@@ -93,6 +120,13 @@
for ( i in blockLikeTags )
defaultDataBlockFilterRules.elements[ i ] = extendBlockForDisplay;
+ var defaultListDataFilterRules = { elements : {} };
+ if( !CKEDITOR.env.ie )
+ {
+ for( i in dtd.$listItem )
+ defaultListDataFilterRules.elements[ i ] = extendNestedListForDisplay;
+ }
+
var defaultHtmlFilterRules =
{
elementNames :
@@ -189,6 +223,13 @@
for ( i in blockLikeTags )
defaultHtmlBlockFilterRules.elements[ i ] = extendBlockForOutput;
+ var defaultListHtmlFilterRules = { elements : {} };
+ if( !CKEDITOR.env.ie )
+ {
+ for( i in dtd.$listItem )
+ defaultListHtmlFilterRules.elements[ i ] = extendNestedListForOutput;
+ }
+
if ( CKEDITOR.env.ie )
{
// IE outputs style attribute in capital letters. We should convert
@@ -293,8 +334,10 @@
dataProcessor.dataFilter.addRules( defaultDataFilterRules );
dataProcessor.dataFilter.addRules( defaultDataBlockFilterRules );
+ dataProcessor.dataFilter.addRules( defaultListDataFilterRules );
dataProcessor.htmlFilter.addRules( defaultHtmlFilterRules );
dataProcessor.htmlFilter.addRules( defaultHtmlBlockFilterRules );
+ dataProcessor.htmlFilter.addRules( defaultListHtmlFilterRules );
}
});