|
|
@@ -52,19 +52,63 @@ describe( 'IndentCommand', () => {
|
|
|
|
|
|
describe( 'isEnabled', () => {
|
|
|
it( 'should be true if selection starts in list item', () => {
|
|
|
- doc.selection.collapse( root.getChild( 5 ) );
|
|
|
+ doc.enqueueChanges( () => {
|
|
|
+ doc.selection.collapse( root.getChild( 5 ) );
|
|
|
+ } );
|
|
|
|
|
|
expect( command.isEnabled ).to.be.true;
|
|
|
} );
|
|
|
|
|
|
it( 'should be false if selection starts in first list item', () => {
|
|
|
- doc.selection.collapse( root.getChild( 0 ) );
|
|
|
+ doc.enqueueChanges( () => {
|
|
|
+ doc.selection.collapse( root.getChild( 0 ) );
|
|
|
+ } );
|
|
|
+
|
|
|
+ expect( command.isEnabled ).to.be.false;
|
|
|
+ } );
|
|
|
+
|
|
|
+ // Reported in PR #53.
|
|
|
+ it( 'should be false if selection starts in first list item #2', () => {
|
|
|
+ setData(
|
|
|
+ doc,
|
|
|
+ '<listItem indent="0" type="bulleted">a</listItem>' +
|
|
|
+ '<listItem indent="1" type="bulleted">b</listItem>' +
|
|
|
+ '<listItem indent="0" type="bulleted">c</listItem>' +
|
|
|
+ '<listItem indent="1" type="bulleted">[]d</listItem>' +
|
|
|
+ '<listItem indent="2" type="bulleted">e</listItem>'
|
|
|
+ );
|
|
|
+
|
|
|
+ expect( command.isEnabled ).to.be.false;
|
|
|
+ } );
|
|
|
+
|
|
|
+ // Reported in PR #53.
|
|
|
+ it( 'should be false if selection starts in first list item #3', () => {
|
|
|
+ setData(
|
|
|
+ doc,
|
|
|
+ '<listItem indent="0" type="bulleted">a</listItem>' +
|
|
|
+ '<listItem indent="1" type="bulleted">b</listItem>' +
|
|
|
+ '<listItem indent="0" type="numbered">c</listItem>' +
|
|
|
+ '<listItem indent="1" type="bulleted">d</listItem>' +
|
|
|
+ '<listItem indent="0" type="bulleted">[]e</listItem>'
|
|
|
+ );
|
|
|
+
|
|
|
+ expect( command.isEnabled ).to.be.false;
|
|
|
+ } );
|
|
|
+
|
|
|
+ it( 'should be false if selection starts in first list item of top level list with different type than previous list', () => {
|
|
|
+ setData(
|
|
|
+ doc,
|
|
|
+ '<listItem indent="0" type="bulleted">a</listItem>' +
|
|
|
+ '<listItem indent="0" type="numbered">[]b</listItem>'
|
|
|
+ );
|
|
|
|
|
|
expect( command.isEnabled ).to.be.false;
|
|
|
} );
|
|
|
|
|
|
it( 'should be false if selection starts in a list item that has bigger indent than it\'s previous sibling', () => {
|
|
|
- doc.selection.collapse( root.getChild( 2 ) );
|
|
|
+ doc.enqueueChanges( () => {
|
|
|
+ doc.selection.collapse( root.getChild( 2 ) );
|
|
|
+ } );
|
|
|
|
|
|
expect( command.isEnabled ).to.be.false;
|
|
|
} );
|
|
|
@@ -73,6 +117,7 @@ describe( 'IndentCommand', () => {
|
|
|
// and before we fixed it the command was enabled in such a case.
|
|
|
it( 'should be false if selection starts in a paragraph with indent attribute', () => {
|
|
|
doc.schema.allow( { name: 'paragraph', attributes: [ 'indent' ], inside: '$root' } );
|
|
|
+
|
|
|
setData( doc, '<listItem indent="0">a</listItem><paragraph indent="0">b[]</paragraph>' );
|
|
|
|
|
|
expect( command.isEnabled ).to.be.false;
|
|
|
@@ -81,7 +126,9 @@ describe( 'IndentCommand', () => {
|
|
|
|
|
|
describe( '_doExecute', () => {
|
|
|
it( 'should increment indent attribute by 1', () => {
|
|
|
- doc.selection.collapse( root.getChild( 5 ) );
|
|
|
+ doc.enqueueChanges( () => {
|
|
|
+ doc.selection.collapse( root.getChild( 5 ) );
|
|
|
+ } );
|
|
|
|
|
|
command._doExecute();
|
|
|
|
|
|
@@ -97,7 +144,9 @@ describe( 'IndentCommand', () => {
|
|
|
} );
|
|
|
|
|
|
it( 'should increment indent of all sub-items of indented item', () => {
|
|
|
- doc.selection.collapse( root.getChild( 1 ) );
|
|
|
+ doc.enqueueChanges( () => {
|
|
|
+ doc.selection.collapse( root.getChild( 1 ) );
|
|
|
+ } );
|
|
|
|
|
|
command._doExecute();
|
|
|
|
|
|
@@ -113,10 +162,12 @@ describe( 'IndentCommand', () => {
|
|
|
} );
|
|
|
|
|
|
it( 'should increment indent of all selected item when multiple items are selected', () => {
|
|
|
- doc.selection.setRanges( [ new Range(
|
|
|
- new Position( root.getChild( 1 ), [ 0 ] ),
|
|
|
- new Position( root.getChild( 3 ), [ 0 ] )
|
|
|
- ) ] );
|
|
|
+ doc.enqueueChanges( () => {
|
|
|
+ doc.selection.setRanges( [ new Range(
|
|
|
+ new Position( root.getChild( 1 ), [ 0 ] ),
|
|
|
+ new Position( root.getChild( 3 ), [ 0 ] )
|
|
|
+ ) ] );
|
|
|
+ } );
|
|
|
|
|
|
command._doExecute();
|
|
|
|
|
|
@@ -130,6 +181,49 @@ describe( 'IndentCommand', () => {
|
|
|
'<listItem indent="0" type="bulleted">g</listItem>'
|
|
|
);
|
|
|
} );
|
|
|
+
|
|
|
+ it( 'should fix list type when item is intended #1', () => {
|
|
|
+ setData(
|
|
|
+ doc,
|
|
|
+ '<listItem indent="0" type="bulleted">a</listItem>' +
|
|
|
+ '<listItem indent="1" type="bulleted">b</listItem>' +
|
|
|
+ '<listItem indent="2" type="numbered">c</listItem>' +
|
|
|
+ '<listItem indent="1" type="bulleted">[]d</listItem>'
|
|
|
+ );
|
|
|
+
|
|
|
+ command._doExecute();
|
|
|
+
|
|
|
+ expect( getData( doc, { withoutSelection: true } ) ).to.equal(
|
|
|
+ '<listItem indent="0" type="bulleted">a</listItem>' +
|
|
|
+ '<listItem indent="1" type="bulleted">b</listItem>' +
|
|
|
+ '<listItem indent="2" type="numbered">c</listItem>' +
|
|
|
+ '<listItem indent="2" type="numbered">d</listItem>'
|
|
|
+ );
|
|
|
+ } );
|
|
|
+
|
|
|
+ // Not only boundary list items has to be fixed, but also items in the middle of selection.
|
|
|
+ it( 'should fix list type when item is intended #2', () => {
|
|
|
+ setData(
|
|
|
+ doc,
|
|
|
+ '<listItem indent="0" type="bulleted">a</listItem>' +
|
|
|
+ '<listItem indent="1" type="numbered">b</listItem>' +
|
|
|
+ '<listItem indent="1" type="numbered">[c</listItem>' +
|
|
|
+ '<listItem indent="0" type="bulleted">d</listItem>' +
|
|
|
+ '<listItem indent="1" type="numbered">e]</listItem>' +
|
|
|
+ '<listItem indent="0" type="bulleted">f</listItem>'
|
|
|
+ );
|
|
|
+
|
|
|
+ command._doExecute();
|
|
|
+
|
|
|
+ expect( getData( doc, { withoutSelection: true } ) ).to.equal(
|
|
|
+ '<listItem indent="0" type="bulleted">a</listItem>' +
|
|
|
+ '<listItem indent="1" type="numbered">b</listItem>' +
|
|
|
+ '<listItem indent="2" type="numbered">c</listItem>' +
|
|
|
+ '<listItem indent="1" type="numbered">d</listItem>' +
|
|
|
+ '<listItem indent="2" type="numbered">e</listItem>' +
|
|
|
+ '<listItem indent="0" type="bulleted">f</listItem>'
|
|
|
+ );
|
|
|
+ } );
|
|
|
} );
|
|
|
} );
|
|
|
|
|
|
@@ -146,21 +240,27 @@ describe( 'IndentCommand', () => {
|
|
|
|
|
|
describe( 'isEnabled', () => {
|
|
|
it( 'should be true if selection starts in list item', () => {
|
|
|
- doc.selection.collapse( root.getChild( 5 ) );
|
|
|
+ doc.enqueueChanges( () => {
|
|
|
+ doc.selection.collapse( root.getChild( 5 ) );
|
|
|
+ } );
|
|
|
|
|
|
expect( command.isEnabled ).to.be.true;
|
|
|
} );
|
|
|
|
|
|
it( 'should be true if selection starts in first list item', () => {
|
|
|
// This is in contrary to forward indent command.
|
|
|
- doc.selection.collapse( root.getChild( 0 ) );
|
|
|
+ doc.enqueueChanges( () => {
|
|
|
+ doc.selection.collapse( root.getChild( 0 ) );
|
|
|
+ } );
|
|
|
|
|
|
expect( command.isEnabled ).to.be.true;
|
|
|
} );
|
|
|
|
|
|
it( 'should be true if selection starts in a list item that has bigger indent than it\'s previous sibling', () => {
|
|
|
// This is in contrary to forward indent command.
|
|
|
- doc.selection.collapse( root.getChild( 2 ) );
|
|
|
+ doc.enqueueChanges( () => {
|
|
|
+ doc.selection.collapse( root.getChild( 2 ) );
|
|
|
+ } );
|
|
|
|
|
|
expect( command.isEnabled ).to.be.true;
|
|
|
} );
|
|
|
@@ -168,7 +268,9 @@ describe( 'IndentCommand', () => {
|
|
|
|
|
|
describe( '_doExecute', () => {
|
|
|
it( 'should decrement indent attribute by 1 (if it is bigger than 0)', () => {
|
|
|
- doc.selection.collapse( root.getChild( 5 ) );
|
|
|
+ doc.enqueueChanges( () => {
|
|
|
+ doc.selection.collapse( root.getChild( 5 ) );
|
|
|
+ } );
|
|
|
|
|
|
command._doExecute();
|
|
|
|
|
|
@@ -184,7 +286,9 @@ describe( 'IndentCommand', () => {
|
|
|
} );
|
|
|
|
|
|
it( 'should rename listItem to paragraph (if indent is equal to 0)', () => {
|
|
|
- doc.selection.collapse( root.getChild( 0 ) );
|
|
|
+ doc.enqueueChanges( () => {
|
|
|
+ doc.selection.collapse( root.getChild( 0 ) );
|
|
|
+ } );
|
|
|
|
|
|
command._doExecute();
|
|
|
|
|
|
@@ -200,7 +304,9 @@ describe( 'IndentCommand', () => {
|
|
|
} );
|
|
|
|
|
|
it( 'should decrement indent of all sub-items of outdented item', () => {
|
|
|
- doc.selection.collapse( root.getChild( 1 ) );
|
|
|
+ doc.enqueueChanges( () => {
|
|
|
+ doc.selection.collapse( root.getChild( 1 ) );
|
|
|
+ } );
|
|
|
|
|
|
command._doExecute();
|
|
|
|
|
|
@@ -216,10 +322,12 @@ describe( 'IndentCommand', () => {
|
|
|
} );
|
|
|
|
|
|
it( 'should outdent all selected item when multiple items are selected', () => {
|
|
|
- doc.selection.setRanges( [ new Range(
|
|
|
- new Position( root.getChild( 1 ), [ 0 ] ),
|
|
|
- new Position( root.getChild( 3 ), [ 0 ] )
|
|
|
- ) ] );
|
|
|
+ doc.enqueueChanges( () => {
|
|
|
+ doc.selection.setRanges( [ new Range(
|
|
|
+ new Position( root.getChild( 1 ), [ 0 ] ),
|
|
|
+ new Position( root.getChild( 3 ), [ 0 ] )
|
|
|
+ ) ] );
|
|
|
+ } );
|
|
|
|
|
|
command._doExecute();
|
|
|
|
|
|
@@ -234,18 +342,14 @@ describe( 'IndentCommand', () => {
|
|
|
);
|
|
|
} );
|
|
|
|
|
|
- it( 'should fix list type if item is outdented', () => {
|
|
|
+ it( 'should fix list type when item is outdented #1', () => {
|
|
|
setData(
|
|
|
doc,
|
|
|
'<listItem indent="0" type="bulleted">a</listItem>' +
|
|
|
'<listItem indent="1" type="bulleted">b</listItem>' +
|
|
|
- '<listItem indent="2" type="numbered">c</listItem>'
|
|
|
+ '<listItem indent="2" type="numbered">[]c</listItem>'
|
|
|
);
|
|
|
|
|
|
- doc.selection.setRanges( [ new Range(
|
|
|
- new Position( root.getChild( 2 ), [ 0 ] )
|
|
|
- ) ] );
|
|
|
-
|
|
|
command._doExecute();
|
|
|
|
|
|
expect( getData( doc, { withoutSelection: true } ) ).to.equal(
|
|
|
@@ -255,22 +359,85 @@ describe( 'IndentCommand', () => {
|
|
|
);
|
|
|
} );
|
|
|
|
|
|
- it( 'should not fix list type if item is outdented to top level', () => {
|
|
|
+ // Look at next siblings if, after outdenting, a list item is a first item in it's list (list item "c").
|
|
|
+ it( 'should fix list type when item is outdented #2', () => {
|
|
|
setData(
|
|
|
doc,
|
|
|
'<listItem indent="0" type="bulleted">a</listItem>' +
|
|
|
- '<listItem indent="1" type="numbered">b</listItem>'
|
|
|
+ '<listItem indent="1" type="numbered">[]b</listItem>' +
|
|
|
+ '<listItem indent="2" type="bulleted">c</listItem>' +
|
|
|
+ '<listItem indent="1" type="numbered">d</listItem>'
|
|
|
);
|
|
|
|
|
|
- doc.selection.setRanges( [ new Range(
|
|
|
- new Position( root.getChild( 1 ), [ 0 ] )
|
|
|
- ) ] );
|
|
|
+ command._doExecute();
|
|
|
+
|
|
|
+ expect( getData( doc, { withoutSelection: true } ) ).to.equal(
|
|
|
+ '<listItem indent="0" type="bulleted">a</listItem>' +
|
|
|
+ '<listItem indent="0" type="bulleted">b</listItem>' +
|
|
|
+ '<listItem indent="1" type="numbered">c</listItem>' +
|
|
|
+ '<listItem indent="1" type="numbered">d</listItem>'
|
|
|
+ );
|
|
|
+ } );
|
|
|
+
|
|
|
+ // Reported in #53.
|
|
|
+ it( 'should fix list type when item is outdented #3', () => {
|
|
|
+ setData(
|
|
|
+ doc,
|
|
|
+ '<listItem indent="0" type="bulleted">a</listItem>' +
|
|
|
+ '<listItem indent="1" type="numbered">[b</listItem>' +
|
|
|
+ '<listItem indent="1" type="numbered">c</listItem>' +
|
|
|
+ '<listItem indent="1" type="numbered">d]</listItem>'
|
|
|
+ );
|
|
|
|
|
|
command._doExecute();
|
|
|
|
|
|
expect( getData( doc, { withoutSelection: true } ) ).to.equal(
|
|
|
'<listItem indent="0" type="bulleted">a</listItem>' +
|
|
|
- '<listItem indent="0" type="numbered">b</listItem>'
|
|
|
+ '<listItem indent="0" type="bulleted">b</listItem>' +
|
|
|
+ '<listItem indent="0" type="bulleted">c</listItem>' +
|
|
|
+ '<listItem indent="0" type="bulleted">d</listItem>'
|
|
|
+ );
|
|
|
+ } );
|
|
|
+
|
|
|
+ it( 'should fix list type when item is outdented to top level (if needed)', () => {
|
|
|
+ setData(
|
|
|
+ doc,
|
|
|
+ '<listItem indent="0" type="bulleted">a</listItem>' +
|
|
|
+ '<listItem indent="1" type="numbered">[]b</listItem>' +
|
|
|
+ '<listItem indent="0" type="numbered">c</listItem>'
|
|
|
+ );
|
|
|
+
|
|
|
+ command._doExecute();
|
|
|
+
|
|
|
+ // Another possible behaviour would be that "b" list item becomes first list item of a top level
|
|
|
+ // numbered list (so it does not change it's type) but it seems less correct from UX standpoint.
|
|
|
+ expect( getData( doc, { withoutSelection: true } ) ).to.equal(
|
|
|
+ '<listItem indent="0" type="bulleted">a</listItem>' +
|
|
|
+ '<listItem indent="0" type="bulleted">b</listItem>' +
|
|
|
+ '<listItem indent="0" type="numbered">c</listItem>'
|
|
|
+ );
|
|
|
+ } );
|
|
|
+
|
|
|
+ it( 'should not fix nested list items\' type when not needed', () => {
|
|
|
+ // There was a bug that the nested sub-list changed it's type because for a while, it was on same indent
|
|
|
+ // level as the originally outdented element.
|
|
|
+ setData(
|
|
|
+ doc,
|
|
|
+ '<listItem indent="0" type="bulleted">a</listItem>' +
|
|
|
+ '<listItem indent="1" type="numbered">b</listItem>' +
|
|
|
+ '<listItem indent="1" type="numbered">[]c</listItem>' +
|
|
|
+ '<listItem indent="2" type="bulleted">d</listItem>' +
|
|
|
+ '<listItem indent="2" type="bulleted">e</listItem>'
|
|
|
+ );
|
|
|
+
|
|
|
+ command._doExecute();
|
|
|
+
|
|
|
+ expect( getData( doc, { withoutSelection: true } ) ).to.equal(
|
|
|
+ '<listItem indent="0" type="bulleted">a</listItem>' +
|
|
|
+ '<listItem indent="1" type="numbered">b</listItem>' +
|
|
|
+ '<listItem indent="0" type="bulleted">c</listItem>' +
|
|
|
+ '<listItem indent="1" type="bulleted">d</listItem>' +
|
|
|
+ '<listItem indent="1" type="bulleted">e</listItem>'
|
|
|
);
|
|
|
} );
|
|
|
} );
|