mirror of
https://gerrit.wikimedia.org/r/mediawiki/extensions/VisualEditor
synced 2024-09-25 11:16:51 +00:00
Merge "(bug 37905) Make unlisting unlist all list levels"
This commit is contained in:
commit
12d3afa85c
|
@ -76,32 +76,87 @@ ve.ui.ListButtonTool.prototype.list = function( nodes, style ) {
|
|||
};
|
||||
|
||||
ve.ui.ListButtonTool.prototype.unlist = function( node ) {
|
||||
/**
|
||||
* Recursively prepare to unwrap all lists in a given range.
|
||||
*
|
||||
* This function will find all lists covered wholly or partially by the given range, as well
|
||||
* as all lists inside these lists, and return their inner ranges. This means that all sublists
|
||||
* will be found even if range doesn't cover them.
|
||||
*
|
||||
* To actually unwrap the list, feed the returned ranges to ve.dm.Transaction.newFromWrap(),
|
||||
* in order.
|
||||
*
|
||||
* @param {ve.dm.Document} documentModel
|
||||
* @param {ve.Range} range
|
||||
* @returns {ve.Range[]} Array of inner ranges of lists
|
||||
*/
|
||||
function getUnlistRanges( documentModel, range ) {
|
||||
var groups = documentModel.getCoveredSiblingGroups( range ),
|
||||
// Collect ranges in an object for deduplication
|
||||
unlistRanges = {}, range,
|
||||
i, j, k, group, previousList, list, listItem,
|
||||
subList, endOffset = 0;
|
||||
for ( i = 0; i < groups.length; i++ ) {
|
||||
group = groups[i];
|
||||
list = group.grandparent;
|
||||
if ( list && list.getType() === 'list' && list !== previousList ) {
|
||||
// Unwrap the parent list
|
||||
range = list.getRange();
|
||||
if ( range.end > endOffset ) {
|
||||
unlistRanges[range.start + '-' + range.end] = range;
|
||||
endOffset = range.end;
|
||||
}
|
||||
// Skip this list next time
|
||||
previousList = list;
|
||||
// Recursively unwrap any sublists of the list
|
||||
for ( j = 0; j < list.children.length; j++ ) {
|
||||
listItem = list.children[j];
|
||||
if ( listItem.getType() === 'listItem' ) {
|
||||
for ( k = 0; k < listItem.children.length; k++ ) {
|
||||
subList = listItem.children[k];
|
||||
if ( subList.getType() === 'list' ) {
|
||||
// Recurse
|
||||
unlistRanges = ve.extendObject( unlistRanges, getUnlistRanges(
|
||||
documentModel, subList.getRange()
|
||||
) );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return unlistRanges;
|
||||
}
|
||||
|
||||
var surfaceModel = this.toolbar.getSurfaceView().getModel(),
|
||||
documentModel = surfaceModel.getDocument(),
|
||||
selection = surfaceModel.getSelection(),
|
||||
groups = documentModel.getCoveredSiblingGroups( selection ),
|
||||
previousList,
|
||||
group,
|
||||
tx;
|
||||
for ( var i = 0; i < groups.length; i++ ) {
|
||||
group = groups[i];
|
||||
if ( group.grandparent && group.grandparent.getType() === 'list' ) {
|
||||
if ( group.grandparent !== previousList ) {
|
||||
// Unwrap the parent list
|
||||
tx = ve.dm.Transaction.newFromWrap(
|
||||
documentModel,
|
||||
group.grandparent.getRange(),
|
||||
[ { 'type': 'list' } ],
|
||||
[],
|
||||
[ { 'type': 'listItem' } ],
|
||||
[]
|
||||
);
|
||||
surfaceModel.change( tx, tx.translateRange( selection ) );
|
||||
// Skip this one next time
|
||||
previousList = group.grandparent;
|
||||
}
|
||||
unlistRangesObj = getUnlistRanges( documentModel, selection ),
|
||||
unlistRangesArr = [],
|
||||
i, j;
|
||||
for ( i in unlistRangesObj ) {
|
||||
unlistRangesArr.push( unlistRangesObj[i] );
|
||||
}
|
||||
for ( i = 0; i < unlistRangesArr.length; i++ ) {
|
||||
// Unwrap the range given by unlistRanges[i]
|
||||
tx = ve.dm.Transaction.newFromWrap(
|
||||
documentModel,
|
||||
unlistRangesArr[i],
|
||||
[ { 'type': 'list' } ],
|
||||
[],
|
||||
[ { 'type': 'listItem' } ],
|
||||
[]
|
||||
);
|
||||
selection = tx.translateRange( selection );
|
||||
surfaceModel.change( tx );
|
||||
// Translate all the remaining ranges for this transaction
|
||||
// TODO ideally we'd have a way to merge all these transactions into one and execute that instead
|
||||
for ( j = i + 1; j < unlistRangesArr.length; j++ ) {
|
||||
unlistRangesArr[j] = tx.translateRange( unlistRangesArr[j] );
|
||||
}
|
||||
}
|
||||
// Update the selection
|
||||
surfaceModel.change( null, selection );
|
||||
};
|
||||
|
||||
ve.ui.ListButtonTool.prototype.onClick = function() {
|
||||
|
|
Loading…
Reference in a new issue