|
@@ -1,5 +1,5 @@
|
|
|
/**
|
|
/**
|
|
|
- * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.
|
|
|
|
|
|
|
+ * @license Copyright (c) 2003-2018, CKSource - Frederico Knabben. All rights reserved.
|
|
|
* For licensing, see LICENSE.md.
|
|
* For licensing, see LICENSE.md.
|
|
|
*/
|
|
*/
|
|
|
|
|
|
|
@@ -8,22 +8,30 @@ import HighlightCommand from './../src/highlightcommand';
|
|
|
import Command from '@ckeditor/ckeditor5-core/src/command';
|
|
import Command from '@ckeditor/ckeditor5-core/src/command';
|
|
|
import ModelTestEditor from '@ckeditor/ckeditor5-core/tests/_utils/modeltesteditor';
|
|
import ModelTestEditor from '@ckeditor/ckeditor5-core/tests/_utils/modeltesteditor';
|
|
|
import { getData, setData } from '@ckeditor/ckeditor5-engine/src/dev-utils/model';
|
|
import { getData, setData } from '@ckeditor/ckeditor5-engine/src/dev-utils/model';
|
|
|
|
|
+import Position from '@ckeditor/ckeditor5-engine/src/model/position';
|
|
|
|
|
+import Range from '@ckeditor/ckeditor5-engine/src/model/range';
|
|
|
|
|
|
|
|
describe( 'HighlightCommand', () => {
|
|
describe( 'HighlightCommand', () => {
|
|
|
- let editor, doc, command;
|
|
|
|
|
|
|
+ let editor, model, doc, root, command;
|
|
|
|
|
|
|
|
beforeEach( () => {
|
|
beforeEach( () => {
|
|
|
return ModelTestEditor.create()
|
|
return ModelTestEditor.create()
|
|
|
.then( newEditor => {
|
|
.then( newEditor => {
|
|
|
- doc = newEditor.document;
|
|
|
|
|
- command = new HighlightCommand( newEditor );
|
|
|
|
|
editor = newEditor;
|
|
editor = newEditor;
|
|
|
|
|
+ model = editor.model;
|
|
|
|
|
+ doc = model.document;
|
|
|
|
|
+ root = doc.getRoot();
|
|
|
|
|
|
|
|
|
|
+ command = new HighlightCommand( newEditor );
|
|
|
editor.commands.add( 'highlight', command );
|
|
editor.commands.add( 'highlight', command );
|
|
|
|
|
|
|
|
- doc.schema.registerItem( 'paragraph', '$block' );
|
|
|
|
|
-
|
|
|
|
|
- doc.schema.allow( { name: '$inline', attributes: 'highlight', inside: '$block' } );
|
|
|
|
|
|
|
+ model.schema.register( 'p', { inheritAllFrom: '$block' } );
|
|
|
|
|
+ model.schema.addAttributeCheck( ( ctx, attributeName ) => {
|
|
|
|
|
+ // Allow 'highlight' on p>$text.
|
|
|
|
|
+ if ( ctx.endsWith( 'p $text' ) && attributeName == 'highlight' ) {
|
|
|
|
|
+ return true;
|
|
|
|
|
+ }
|
|
|
|
|
+ } );
|
|
|
} );
|
|
} );
|
|
|
} );
|
|
} );
|
|
|
|
|
|
|
@@ -38,94 +46,210 @@ describe( 'HighlightCommand', () => {
|
|
|
|
|
|
|
|
describe( 'value', () => {
|
|
describe( 'value', () => {
|
|
|
it( 'is set to highlight attribute value when selection is in text with highlight attribute', () => {
|
|
it( 'is set to highlight attribute value when selection is in text with highlight attribute', () => {
|
|
|
- setData( doc, '<paragraph><$text highlight="marker">fo[]o</$text></paragraph>' );
|
|
|
|
|
|
|
+ setData( model, '<p><$text highlight="yellowMarker">fo[o]</$text></p>' );
|
|
|
|
|
|
|
|
- expect( command ).to.have.property( 'value', 'marker' );
|
|
|
|
|
|
|
+ expect( command ).to.have.property( 'value', 'yellowMarker' );
|
|
|
} );
|
|
} );
|
|
|
|
|
|
|
|
it( 'is undefined when selection is not in text with highlight attribute', () => {
|
|
it( 'is undefined when selection is not in text with highlight attribute', () => {
|
|
|
- setData( doc, '<paragraph>fo[]o</paragraph>' );
|
|
|
|
|
|
|
+ setData( model, '<p>fo[]o</p>' );
|
|
|
|
|
|
|
|
expect( command ).to.have.property( 'value', undefined );
|
|
expect( command ).to.have.property( 'value', undefined );
|
|
|
} );
|
|
} );
|
|
|
} );
|
|
} );
|
|
|
|
|
|
|
|
describe( 'isEnabled', () => {
|
|
describe( 'isEnabled', () => {
|
|
|
|
|
+ beforeEach( () => {
|
|
|
|
|
+ model.schema.register( 'x', { inheritAllFrom: '$block' } );
|
|
|
|
|
+ } );
|
|
|
|
|
+
|
|
|
it( 'is true when selection is on text which can have highlight added', () => {
|
|
it( 'is true when selection is on text which can have highlight added', () => {
|
|
|
- setData( doc, '<paragraph>fo[]o</paragraph>' );
|
|
|
|
|
|
|
+ setData( model, '<p>fo[]o</p>' );
|
|
|
|
|
|
|
|
expect( command ).to.have.property( 'isEnabled', true );
|
|
expect( command ).to.have.property( 'isEnabled', true );
|
|
|
} );
|
|
} );
|
|
|
|
|
+
|
|
|
|
|
+ it( 'is false when selection is on text which can not have highlight added', () => {
|
|
|
|
|
+ setData( model, '<x>fo[]o</x>' );
|
|
|
|
|
+ expect( command.isEnabled ).to.be.false;
|
|
|
|
|
+ } );
|
|
|
} );
|
|
} );
|
|
|
|
|
|
|
|
describe( 'execute()', () => {
|
|
describe( 'execute()', () => {
|
|
|
- it( 'should add highlight attribute on selected nodes nodes when passed as parameter', () => {
|
|
|
|
|
- setData( doc, '<paragraph>a[bc<$text highlight="marker">fo]obar</$text>xyz</paragraph>' );
|
|
|
|
|
|
|
+ describe( 'with option.value set', () => {
|
|
|
|
|
+ describe( 'on collapsed range', () => {
|
|
|
|
|
+ it( 'should change entire highlight when inside highlighted text', () => {
|
|
|
|
|
+ setData( model, '<p>abc<$text highlight="yellowMarker">foo[]bar</$text>xyz</p>' );
|
|
|
|
|
|
|
|
- expect( command.value ).to.be.undefined;
|
|
|
|
|
|
|
+ expect( command.value ).to.equal( 'yellowMarker' );
|
|
|
|
|
|
|
|
- command.execute( { class: 'marker' } );
|
|
|
|
|
|
|
+ command.execute( { value: 'greenMarker' } );
|
|
|
|
|
|
|
|
- expect( command.value ).to.equal( 'marker' );
|
|
|
|
|
|
|
+ expect( getData( model ) ).to.equal( '<p>abc<$text highlight="greenMarker">foo[]bar</$text>xyz</p>' );
|
|
|
|
|
|
|
|
- expect( getData( doc ) ).to.equal( '<paragraph>a[<$text highlight="marker">bcfo]obar</$text>xyz</paragraph>' );
|
|
|
|
|
- } );
|
|
|
|
|
|
|
+ expect( command.value ).to.equal( 'greenMarker' );
|
|
|
|
|
+ } );
|
|
|
|
|
|
|
|
- it( 'should add highlight attribute on selected nodes nodes when passed as parameter (multiple nodes)', () => {
|
|
|
|
|
- setData(
|
|
|
|
|
- doc,
|
|
|
|
|
- '<paragraph>abcabc[abc</paragraph>' +
|
|
|
|
|
- '<paragraph>foofoofoo</paragraph>' +
|
|
|
|
|
- '<paragraph>barbar]bar</paragraph>'
|
|
|
|
|
- );
|
|
|
|
|
|
|
+ it( 'should remove entire highlight when inside highlighted text of the same value', () => {
|
|
|
|
|
+ setData( model, '<p>abc<$text highlight="yellowMarker">foo[]bar</$text>xyz</p>' );
|
|
|
|
|
|
|
|
- command.execute( { class: 'marker' } );
|
|
|
|
|
|
|
+ expect( command.value ).to.equal( 'yellowMarker' );
|
|
|
|
|
|
|
|
- expect( command.value ).to.equal( 'marker' );
|
|
|
|
|
|
|
+ command.execute( { value: 'yellowMarker' } );
|
|
|
|
|
|
|
|
- expect( getData( doc ) ).to.equal(
|
|
|
|
|
- '<paragraph>abcabc[<$text highlight="marker">abc</$text></paragraph>' +
|
|
|
|
|
- '<paragraph><$text highlight="marker">foofoofoo</$text></paragraph>' +
|
|
|
|
|
- '<paragraph><$text highlight="marker">barbar</$text>]bar</paragraph>'
|
|
|
|
|
- );
|
|
|
|
|
- } );
|
|
|
|
|
|
|
+ expect( getData( model ) ).to.equal( '<p>abcfoo[]barxyz</p>' );
|
|
|
|
|
|
|
|
- it( 'should set highlight attribute on selected nodes when passed as parameter', () => {
|
|
|
|
|
- setData( doc, '<paragraph>abc[<$text highlight="marker">foo]bar</$text>xyz</paragraph>' );
|
|
|
|
|
|
|
+ expect( command.value ).to.be.undefined;
|
|
|
|
|
+ } );
|
|
|
|
|
|
|
|
- expect( command.value ).to.equal( 'marker' );
|
|
|
|
|
|
|
+ it( 'should change selection attribute in non-empty parent', () => {
|
|
|
|
|
+ setData( model, '<p>a[]bc<$text highlight="yellowMarker">foobar</$text>xyz</p>' );
|
|
|
|
|
+ expect( command.value ).to.be.undefined;
|
|
|
|
|
|
|
|
- command.execute( { class: 'foo' } );
|
|
|
|
|
|
|
+ command.execute( { value: 'foo' } );
|
|
|
|
|
+ expect( command.value ).to.equal( 'foo' );
|
|
|
|
|
|
|
|
- expect( getData( doc ) ).to.equal(
|
|
|
|
|
- '<paragraph>abc[<$text highlight="foo">foo</$text>]<$text highlight="marker">bar</$text>xyz</paragraph>'
|
|
|
|
|
- );
|
|
|
|
|
|
|
+ expect( doc.selection.hasAttribute( 'highlight' ) ).to.be.true;
|
|
|
|
|
|
|
|
- expect( command.value ).to.equal( 'foo' );
|
|
|
|
|
- } );
|
|
|
|
|
|
|
+ command.execute();
|
|
|
|
|
+
|
|
|
|
|
+ expect( command.value ).to.be.undefined;
|
|
|
|
|
+ expect( doc.selection.hasAttribute( 'highlight' ) ).to.be.false;
|
|
|
|
|
+
|
|
|
|
|
+ // Execute remove highlight on selection without 'highlight' attribute should do nothing.
|
|
|
|
|
+ command.execute();
|
|
|
|
|
+
|
|
|
|
|
+ expect( command.value ).to.be.undefined;
|
|
|
|
|
+ expect( doc.selection.hasAttribute( 'highlight' ) ).to.be.false;
|
|
|
|
|
+ } );
|
|
|
|
|
+
|
|
|
|
|
+ it( 'should not store attribute change on selection if selection is collapsed in non-empty parent', () => {
|
|
|
|
|
+ setData( model, '<p>a[]bc<$text highlight="yellowMarker">foobar</$text>xyz</p>' );
|
|
|
|
|
+
|
|
|
|
|
+ command.execute( { value: 'foo' } );
|
|
|
|
|
+
|
|
|
|
|
+ // It should not save that bold was executed at position ( root, [ 0, 1 ] ).
|
|
|
|
|
+
|
|
|
|
|
+ model.change( writer => {
|
|
|
|
|
+ // Simulate clicking right arrow key by changing selection ranges.
|
|
|
|
|
+ writer.setSelection( [ new Range( new Position( root, [ 0, 2 ] ), new Position( root, [ 0, 2 ] ) ) ] );
|
|
|
|
|
+
|
|
|
|
|
+ // Get back to previous selection.
|
|
|
|
|
+ writer.setSelection( [ new Range( new Position( root, [ 0, 1 ] ), new Position( root, [ 0, 1 ] ) ) ] );
|
|
|
|
|
+ } );
|
|
|
|
|
+
|
|
|
|
|
+ expect( command.value ).to.be.undefined;
|
|
|
|
|
+ } );
|
|
|
|
|
+
|
|
|
|
|
+ it( 'should change selection attribute and store it if selection is collapsed in empty parent', () => {
|
|
|
|
|
+ setData( model, '<p>abc<$text highlight="yellowMarker">foobar</$text>xyz</p><p>[]</p>' );
|
|
|
|
|
+
|
|
|
|
|
+ expect( command.value ).to.be.undefined;
|
|
|
|
|
+
|
|
|
|
|
+ command.execute( { value: 'foo' } );
|
|
|
|
|
+
|
|
|
|
|
+ expect( command.value ).to.equal( 'foo' );
|
|
|
|
|
+ expect( doc.selection.hasAttribute( 'highlight' ) ).to.be.true;
|
|
|
|
|
+
|
|
|
|
|
+ // Attribute should be stored.
|
|
|
|
|
+ // Simulate clicking somewhere else in the editor.
|
|
|
|
|
+ model.change( writer => {
|
|
|
|
|
+ writer.setSelection( [ new Range( new Position( root, [ 0, 2 ] ), new Position( root, [ 0, 2 ] ) ) ] );
|
|
|
|
|
+ } );
|
|
|
|
|
|
|
|
- it( 'should remove highlight attribute on selected nodes nodes when undefined passed as parameter', () => {
|
|
|
|
|
- setData( doc, '<paragraph>abc[<$text highlight="marker">foo]bar</$text>xyz</paragraph>' );
|
|
|
|
|
|
|
+ expect( command.value ).to.be.undefined;
|
|
|
|
|
|
|
|
- expect( command.value ).to.equal( 'marker' );
|
|
|
|
|
|
|
+ // Go back to where attribute was stored.
|
|
|
|
|
+ model.change( writer => {
|
|
|
|
|
+ writer.setSelection( [ new Range( new Position( root, [ 1, 0 ] ), new Position( root, [ 1, 0 ] ) ) ] );
|
|
|
|
|
+ } );
|
|
|
|
|
|
|
|
- command.execute();
|
|
|
|
|
|
|
+ // Attribute should be restored.
|
|
|
|
|
+ expect( command.value ).to.equal( 'foo' );
|
|
|
|
|
|
|
|
- expect( getData( doc ) ).to.equal( '<paragraph>abc[foo]<$text highlight="marker">bar</$text>xyz</paragraph>' );
|
|
|
|
|
|
|
+ command.execute();
|
|
|
|
|
|
|
|
- expect( command.value ).to.be.undefined;
|
|
|
|
|
|
|
+ expect( command.value ).to.be.undefined;
|
|
|
|
|
+ expect( doc.selection.hasAttribute( 'highlight' ) ).to.be.false;
|
|
|
|
|
+ } );
|
|
|
|
|
+ } );
|
|
|
|
|
+
|
|
|
|
|
+ describe( 'on not collapsed range', () => {
|
|
|
|
|
+ it( 'should set highlight attribute on selected node when passed as parameter', () => {
|
|
|
|
|
+ setData( model, '<p>a[bc<$text highlight="yellowMarker">fo]obar</$text>xyz</p>' );
|
|
|
|
|
+
|
|
|
|
|
+ expect( command.value ).to.be.undefined;
|
|
|
|
|
+
|
|
|
|
|
+ command.execute( { value: 'yellowMarker' } );
|
|
|
|
|
+
|
|
|
|
|
+ expect( command.value ).to.equal( 'yellowMarker' );
|
|
|
|
|
+
|
|
|
|
|
+ expect( getData( model ) ).to.equal( '<p>a[<$text highlight="yellowMarker">bcfo]obar</$text>xyz</p>' );
|
|
|
|
|
+ } );
|
|
|
|
|
+
|
|
|
|
|
+ it( 'should set highlight attribute on selected node when passed as parameter (multiple nodes)', () => {
|
|
|
|
|
+ setData(
|
|
|
|
|
+ model,
|
|
|
|
|
+ '<p>abcabc[abc</p>' +
|
|
|
|
|
+ '<p>foofoofoo</p>' +
|
|
|
|
|
+ '<p>barbar]bar</p>'
|
|
|
|
|
+ );
|
|
|
|
|
+
|
|
|
|
|
+ command.execute( { value: 'yellowMarker' } );
|
|
|
|
|
+
|
|
|
|
|
+ expect( command.value ).to.equal( 'yellowMarker' );
|
|
|
|
|
+
|
|
|
|
|
+ expect( getData( model ) ).to.equal(
|
|
|
|
|
+ '<p>abcabc[<$text highlight="yellowMarker">abc</$text></p>' +
|
|
|
|
|
+ '<p><$text highlight="yellowMarker">foofoofoo</$text></p>' +
|
|
|
|
|
+ '<p><$text highlight="yellowMarker">barbar</$text>]bar</p>'
|
|
|
|
|
+ );
|
|
|
|
|
+ } );
|
|
|
|
|
+
|
|
|
|
|
+ it( 'should set highlight attribute on selected nodes when passed as parameter only on selected characters', () => {
|
|
|
|
|
+ setData( model, '<p>abc[<$text highlight="yellowMarker">foo]bar</$text>xyz</p>' );
|
|
|
|
|
+
|
|
|
|
|
+ expect( command.value ).to.equal( 'yellowMarker' );
|
|
|
|
|
+
|
|
|
|
|
+ command.execute( { value: 'foo' } );
|
|
|
|
|
+
|
|
|
|
|
+ expect( getData( model ) ).to.equal(
|
|
|
|
|
+ '<p>abc[<$text highlight="foo">foo</$text>]<$text highlight="yellowMarker">bar</$text>xyz</p>'
|
|
|
|
|
+ );
|
|
|
|
|
+
|
|
|
|
|
+ expect( command.value ).to.equal( 'foo' );
|
|
|
|
|
+ } );
|
|
|
|
|
+ } );
|
|
|
} );
|
|
} );
|
|
|
|
|
|
|
|
- it( 'should do nothing on collapsed range', () => {
|
|
|
|
|
- setData( doc, '<paragraph>abc<$text highlight="marker">foo[]bar</$text>xyz</paragraph>' );
|
|
|
|
|
|
|
+ describe( 'with undefined option.value', () => {
|
|
|
|
|
+ describe( 'on collapsed range', () => {
|
|
|
|
|
+ it( 'should remove entire highlight when inside highlighted text', () => {
|
|
|
|
|
+ setData( model, '<p>abc<$text highlight="yellowMarker">foo[]bar</$text>xyz</p>' );
|
|
|
|
|
+
|
|
|
|
|
+ expect( command.value ).to.equal( 'yellowMarker' );
|
|
|
|
|
|
|
|
- expect( command.value ).to.equal( 'marker' );
|
|
|
|
|
|
|
+ command.execute();
|
|
|
|
|
|
|
|
- command.execute();
|
|
|
|
|
|
|
+ expect( getData( model ) ).to.equal( '<p>abcfoo[]barxyz</p>' );
|
|
|
|
|
|
|
|
- expect( getData( doc ) ).to.equal( '<paragraph>abc<$text highlight="marker">foo[]bar</$text>xyz</paragraph>' );
|
|
|
|
|
|
|
+ expect( command.value ).to.be.undefined;
|
|
|
|
|
+ } );
|
|
|
|
|
+ } );
|
|
|
|
|
|
|
|
- expect( command.value ).to.equal( 'marker' );
|
|
|
|
|
|
|
+ describe( 'on not collapsed range', () => {
|
|
|
|
|
+ it( 'should remove highlight attribute on selected node when undefined passed as parameter', () => {
|
|
|
|
|
+ setData( model, '<p>abc[<$text highlight="yellowMarker">foo]bar</$text>xyz</p>' );
|
|
|
|
|
+
|
|
|
|
|
+ expect( command.value ).to.equal( 'yellowMarker' );
|
|
|
|
|
+
|
|
|
|
|
+ command.execute();
|
|
|
|
|
+
|
|
|
|
|
+ expect( getData( model ) ).to.equal( '<p>abc[foo]<$text highlight="yellowMarker">bar</$text>xyz</p>' );
|
|
|
|
|
+
|
|
|
|
|
+ expect( command.value ).to.be.undefined;
|
|
|
|
|
+ } );
|
|
|
|
|
+ } );
|
|
|
} );
|
|
} );
|
|
|
} );
|
|
} );
|
|
|
} );
|
|
} );
|