Merge "(bug 37905) Make unlisting unlist all list levels"

This commit is contained in:
Trevor Parscal 2012-07-26 18:53:00 +00:00 committed by Gerrit Code Review
commit 12d3afa85c

View file

@ -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() {