mirror of
https://gerrit.wikimedia.org/r/mediawiki/extensions/VisualEditor
synced 2024-11-15 10:35:48 +00:00
Fix unindent action when acting on multiple list items
This is caused by a limitation of surface fragments in that they always expand to include insertions touching them. In this case we build surface fragments contain adjacent listItems, so when the first listItem is de-listed a transaction is first created to split the list. This insertion of ('/list', 'list') is adjacent to the second surface fragment and so becomes part of that fragment. This then causes the wrong node to be passed to unindentListItem. The workaround is to use the inner range of the listItem, not the outer range. Bug: 48390 Change-Id: I7418910412d292ef4953e294a97f66e48d6f776f
This commit is contained in:
parent
da4ddbc4d9
commit
1261a5f471
|
@ -93,7 +93,7 @@ ve.IndentationAction.prototype.decrease = function () {
|
|||
for ( i = 0; i < groups.length; i++ ) {
|
||||
group = groups[i];
|
||||
if ( group.grandparent && group.grandparent.getType() === 'list' ) {
|
||||
fragments.push( surfaceModel.getFragment( group.parent.getOuterRange(), true ) );
|
||||
fragments.push( surfaceModel.getFragment( group.parent.getRange(), true ) );
|
||||
decreased = true;
|
||||
}
|
||||
}
|
||||
|
@ -101,7 +101,7 @@ ve.IndentationAction.prototype.decrease = function () {
|
|||
// Process each fragment (their ranges are automatically adjusted on change)
|
||||
for ( i = 0; i < fragments.length; i++ ) {
|
||||
this.unindentListItem(
|
||||
documentModel.getNodeFromOffset( fragments[i].getRange().start + 1 )
|
||||
documentModel.getNodeFromOffset( fragments[i].getRange().start )
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -117,8 +117,12 @@ ve.IndentationAction.prototype.decrease = function () {
|
|||
*
|
||||
* @method
|
||||
* @param {ve.dm.ListItemNode} listItem List item to indent
|
||||
* @throws {Error} listItem must be a ve.dm.ListItemNode
|
||||
*/
|
||||
ve.IndentationAction.prototype.indentListItem = function ( listItem ) {
|
||||
if ( !( listItem instanceof ve.dm.ListItemNode ) ) {
|
||||
throw new Error( 'listItem must be a ve.dm.ListItemNode' );
|
||||
}
|
||||
/*
|
||||
* Indenting a list item is done as follows:
|
||||
* 1. Wrap the listItem in a list and a listItem (<li> --> <li><ul><li>)
|
||||
|
@ -191,8 +195,12 @@ ve.IndentationAction.prototype.indentListItem = function ( listItem ) {
|
|||
*
|
||||
* @method
|
||||
* @param {ve.dm.ListItemNode} listItem List item to unindent
|
||||
* @throws {Error} listItem must be a ve.dm.ListItemNode
|
||||
*/
|
||||
ve.IndentationAction.prototype.unindentListItem = function ( listItem ) {
|
||||
if ( !( listItem instanceof ve.dm.ListItemNode ) ) {
|
||||
throw new Error( 'listItem must be a ve.dm.ListItemNode' );
|
||||
}
|
||||
/*
|
||||
* Outdenting a list item is done as follows:
|
||||
* 1. Split the parent list to isolate the listItem in its own list
|
||||
|
|
|
@ -52,6 +52,24 @@ QUnit.test( 'decrease', 2, function ( assert ) {
|
|||
delete data[12].internal;
|
||||
},
|
||||
'msg': 'decrease indentation on partial selection of list item "Item 2"'
|
||||
},
|
||||
{
|
||||
'range': new ve.Range( 3, 19 ),
|
||||
'method': 'decrease',
|
||||
'expectedSelection': new ve.Range( 1, 15 ),
|
||||
'expectedData': function ( data ) {
|
||||
data.splice( 0, 2 );
|
||||
data.splice( 8, 2 );
|
||||
data.splice( 16, 1, { 'type': 'list', 'attributes': { 'style': 'bullet' } } );
|
||||
delete data[0].internal;
|
||||
delete data[8].internal;
|
||||
},
|
||||
'expectedOriginalData': function ( data ) {
|
||||
// generated: 'wrapper' is removed by the action and not restored by undo
|
||||
delete data[2].internal;
|
||||
delete data[12].internal;
|
||||
},
|
||||
'msg': 'decrease indentation on Items 1 & 2'
|
||||
}
|
||||
];
|
||||
|
||||
|
|
Loading…
Reference in a new issue