Esanders has uploaded a new change for review. https://gerrit.wikimedia.org/r/300578
Change subject: Ensure document slices which consist of content nodes get wrapped ...................................................................... Ensure document slices which consist of content nodes get wrapped We make sure document slices are balanced, but we also need to make sure that every document contains at least one branch node. Change-Id: I7272613e48a998c1787bcfefb2fca47869f07b60 --- M src/dm/ve.dm.Document.js M tests/dm/ve.dm.Document.test.js 2 files changed, 53 insertions(+), 24 deletions(-) git pull ssh://gerrit.wikimedia.org:29418/VisualEditor/VisualEditor refs/changes/78/300578/1 diff --git a/src/dm/ve.dm.Document.js b/src/dm/ve.dm.Document.js index 6507a13..0e7201f 100644 --- a/src/dm/ve.dm.Document.js +++ b/src/dm/ve.dm.Document.js @@ -454,7 +454,7 @@ ve.dm.Document.prototype.shallowCloneFromRange = function ( range ) { var i, first, last, firstNode, lastNode, linearData, slice, originalRange, balancedRange, - balancedNodes, needsContext, + balancedNodes, needsContext, contextElement, startNode = this.getBranchNodeFromOffset( range.start ), endNode = this.getBranchNodeFromOffset( range.end ), selection = this.selectNodes( range, 'siblings' ), @@ -477,8 +477,11 @@ if ( selection.length === 0 ) { // Nothing selected - linearData = new ve.dm.ElementLinearData( this.getStore(), [] ); - originalRange = balancedRange = new ve.Range( 0 ); + linearData = new ve.dm.ElementLinearData( this.getStore(), [ + { type: 'paragraph', internal: { generated: 'empty' } }, + { type: 'paragraph' } + ] ); + originalRange = balancedRange = new ve.Range( 1 ); } else if ( startNode === endNode ) { // Nothing to balance balancedNodes = selection; @@ -527,11 +530,15 @@ ); } + function nodeNeedsContext( node ) { + return node.getParentNodeTypes() !== null || node.isContent(); + } + if ( !balancedRange ) { // Check if any of the balanced siblings need more context for insertion anywhere needsContext = false; for ( i = balancedNodes.length - 1; i >= 0; i-- ) { - if ( balancedNodes[ i ].node.getParentNodeTypes() !== null ) { + if ( nodeNeedsContext( balancedNodes[ i ].node ) ) { needsContext = true; break; } @@ -540,10 +547,11 @@ if ( needsContext ) { startNode = balancedNodes[ 0 ].node; // Keep wrapping until the outer node can be inserted anywhere - while ( startNode.getParent() && startNode.getParentNodeTypes() !== null ) { + while ( startNode.getParent() && nodeNeedsContext( startNode ) ) { startNode = startNode.getParent(); - contextOpenings.push( startNode.getClonedElement() ); - contextClosings.push( { type: '/' + startNode.getType() } ); + contextElement = startNode.getClonedElement(); + contextOpenings.push( contextElement ); + contextClosings.push( { type: '/' + contextElement.type } ); } } diff --git a/tests/dm/ve.dm.Document.test.js b/tests/dm/ve.dm.Document.test.js index cf3cc37..e2d0f1a 100644 --- a/tests/dm/ve.dm.Document.test.js +++ b/tests/dm/ve.dm.Document.test.js @@ -633,22 +633,35 @@ { msg: 'empty range', range: new ve.Range( 2 ), - expected: [] + expected: [ + { type: 'paragraph', internal: { generated: 'empty' } }, + { type: 'paragraph' } + ], + originalRange: new ve.Range( 1 ), + balancedRange: new ve.Range( 1 ) }, { msg: 'range with one character', range: new ve.Range( 2, 3 ), expected: [ - [ 'b', [ ve.dm.example.bold ] ] - ] + { type: 'heading', attributes: { level: 1 } }, + [ 'b', [ ve.dm.example.bold ] ], + { type: '/heading' } + ], + originalRange: new ve.Range( 1, 2 ), + balancedRange: new ve.Range( 1, 2 ) }, { msg: 'range with two characters', range: new ve.Range( 2, 4 ), expected: [ + { type: 'heading', attributes: { level: 1 } }, [ 'b', [ ve.dm.example.bold ] ], - [ 'c', [ ve.dm.example.italic ] ] - ] + [ 'c', [ ve.dm.example.italic ] ], + { type: '/heading' } + ], + originalRange: new ve.Range( 1, 3 ), + balancedRange: new ve.Range( 1, 3 ) }, { msg: 'range with two characters and a header closing', @@ -792,46 +805,54 @@ msg: 'inline node at start', range: new ve.Range( 1, 3 ), expected: [ + { type: 'paragraph' }, ve.dm.example.image.data, - { type: '/inlineImage' } + { type: '/inlineImage' }, + { type: '/paragraph' } ], - originalRange: new ve.Range( 0, 2 ), - balancedRange: new ve.Range( 0, 2 ) + originalRange: new ve.Range( 1, 3 ), + balancedRange: new ve.Range( 1, 3 ) }, { doc: 'inlineAtEdges', msg: 'inline node at end', range: new ve.Range( 6, 8 ), expected: [ + { type: 'paragraph' }, { type: 'alienInline', originalDomElements: $( '<foobar />' ).toArray() }, - { type: '/alienInline' } + { type: '/alienInline' }, + { type: '/paragraph' } ], - originalRange: new ve.Range( 0, 2 ), - balancedRange: new ve.Range( 0, 2 ) + originalRange: new ve.Range( 1, 3 ), + balancedRange: new ve.Range( 1, 3 ) }, { doc: 'inlineAtEdges', msg: 'inline node at start with text', range: new ve.Range( 1, 5 ), expected: [ + { type: 'paragraph' }, ve.dm.example.image.data, { type: '/inlineImage' }, - 'F', 'o' + 'F', 'o', + { type: '/paragraph' } ], - originalRange: new ve.Range( 0, 4 ), - balancedRange: new ve.Range( 0, 4 ) + originalRange: new ve.Range( 1, 5 ), + balancedRange: new ve.Range( 1, 5 ) }, { doc: 'inlineAtEdges', msg: 'inline node at end with text', range: new ve.Range( 4, 8 ), expected: [ + { type: 'paragraph' }, 'o', 'o', { type: 'alienInline', originalDomElements: $( '<foobar />' ).toArray() }, - { type: '/alienInline' } + { type: '/alienInline' }, + { type: '/paragraph' } ], - originalRange: new ve.Range( 0, 4 ), - balancedRange: new ve.Range( 0, 4 ) + originalRange: new ve.Range( 1, 5 ), + balancedRange: new ve.Range( 1, 5 ) } ]; QUnit.expect( 3 * cases.length ); -- To view, visit https://gerrit.wikimedia.org/r/300578 To unsubscribe, visit https://gerrit.wikimedia.org/r/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I7272613e48a998c1787bcfefb2fca47869f07b60 Gerrit-PatchSet: 1 Gerrit-Project: VisualEditor/VisualEditor Gerrit-Branch: master Gerrit-Owner: Esanders <esand...@wikimedia.org> _______________________________________________ MediaWiki-commits mailing list MediaWiki-commits@lists.wikimedia.org https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits