if ( !baseArray )\r
baseArray = [];\r
\r
- // Iterate over all list items to get their contents and look for inner lists.\r
+ // Iterate over all list items to and look for inner lists.\r
for ( var i = 0, count = listNode.getChildCount() ; i < count ; i++ )\r
{\r
var listItem = listNode.getChild( i );\r
// It may be a text node or some funny stuff.\r
if ( listItem.$.nodeName.toLowerCase() != 'li' )\r
continue;\r
- var itemObj = { 'parent' : listNode, indent : baseIndentLevel, contents : [] };\r
+\r
+ var itemObj = { 'parent' : listNode, indent : baseIndentLevel, element : listItem, contents : [] };\r
if ( !grandparentNode )\r
{\r
itemObj.grandparent = listNode.getParent();\r
CKEDITOR.dom.element.setMarker( database, listItem, 'listarray_index', baseArray.length );\r
baseArray.push( itemObj );\r
\r
- for ( var j = 0, itemChildCount = listItem.getChildCount() ; j < itemChildCount ; j++ )\r
+ for ( var j = 0, itemChildCount = listItem.getChildCount(), child; j < itemChildCount ; j++ )\r
{\r
- var child = listItem.getChild( j );\r
+ child = listItem.getChild( j );\r
if ( child.type == CKEDITOR.NODE_ELEMENT && listNodeNames[ child.getName() ] )\r
// Note the recursion here, it pushes inner list items with\r
// +1 indentation in the correct order.\r
rootNode = listArray[ currentIndex ].parent.clone( false, true );\r
retval.append( rootNode );\r
}\r
- currentListItem = rootNode.append( doc.createElement( 'li' ) );\r
+ currentListItem = rootNode.append( item.element.clone( false, true ) );\r
for ( var i = 0 ; i < item.contents.length ; i++ )\r
currentListItem.append( item.contents[i].clone( true, true ) );\r
currentIndex++;\r
{\r
currentListItem;\r
if ( listNodeNames[ item.grandparent.getName() ] )\r
- currentListItem = doc.createElement( 'li' );\r
+ currentListItem = item.element.clone( false, true );\r
else\r
{\r
+ // Create completely new blocks here, attributes are dropped.\r
if ( paragraphMode != CKEDITOR.ENTER_BR && item.grandparent.getName() != 'td' )\r
currentListItem = doc.createElement( paragraphName );\r
else\r
newList.listNode.replace( groupObj.root );\r
}\r
\r
+ var headerTagRegex = /^h[1-6]$/;\r
+\r
function createList( editor, groupObj, listsCreated )\r
{\r
var contents = groupObj.contents,\r
{\r
var contentBlock = listContents.shift(),\r
listItem = doc.createElement( 'li' );\r
- contentBlock.moveChildren( listItem );\r
- contentBlock.remove();\r
+\r
+ // Preserve heading structure when converting to list item. (#5271)\r
+ if ( headerTagRegex.test( contentBlock.getName() ) )\r
+ contentBlock.appendTo( listItem );\r
+ else\r
+ {\r
+ contentBlock.copyAttributes( listItem );\r
+ contentBlock.moveChildren( listItem );\r
+ contentBlock.remove();\r
+ }\r
+\r
listItem.appendTo( listNode );\r
\r
// Append a bogus BR to force the LI to render at full height\r
nodeBefore = firstNestedList && firstNestedList.previous,\r
tailNbspmatch;\r
\r
- if( nodeBefore\r
+ if ( nodeBefore\r
&& ( nodeBefore.name && nodeBefore.name == 'br'\r
|| nodeBefore.value && ( tailNbspmatch = nodeBefore.value.match( tailNbspRegex ) ) ) )\r
{\r
}\r
\r
var defaultListDataFilterRules = { elements : {} };\r
- for( var i in dtd.$listItem )\r
+ for ( var i in dtd.$listItem )\r
defaultListDataFilterRules.elements[ i ] = getExtendNestedListFilter();\r
\r
var defaultListHtmlFilterRules = { elements : {} };\r
- for( i in dtd.$listItem )\r
+ for ( i in dtd.$listItem )\r
defaultListHtmlFilterRules.elements[ i ] = getExtendNestedListFilter( true );\r
\r
CKEDITOR.plugins.add( 'list',\r
afterInit : function ( editor )\r
{\r
var dataProcessor = editor.dataProcessor;\r
- if( dataProcessor )\r
+ if ( dataProcessor )\r
{\r
dataProcessor.dataFilter.addRules( defaultListDataFilterRules );\r
dataProcessor.htmlFilter.addRules( defaultListHtmlFilterRules );\r