From 3f7a0ada2749e3e3e6720aaeb39ef3fcf8eb6b73 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Krzto=C5=84?= Date: Mon, 13 Mar 2017 09:39:50 +0100 Subject: [PATCH 1/7] InputCommand accepts Range instead of Position as a parameter. --- src/input.js | 6 +++--- src/inputcommand.js | 8 ++++---- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/input.js b/src/input.js index 68c9db1..cb85264 100644 --- a/src/input.js +++ b/src/input.js @@ -184,10 +184,10 @@ class MutationHandler { } // Try setting new model selection according to passed view selection. - let modelSelectionPosition = null; + let modelSelectionRange = null; if ( viewSelection ) { - modelSelectionPosition = this.editing.mapper.toModelPosition( viewSelection.anchor ); + modelSelectionRange = this.editing.mapper.toModelRange( viewSelection.getFirstRange() ); } // Get the position in view and model where the changes will happen. @@ -199,7 +199,7 @@ class MutationHandler { this.editor.execute( 'input', { text: insertText, range: removeRange, - resultPosition: modelSelectionPosition + resultRange: modelSelectionRange } ); } diff --git a/src/inputcommand.js b/src/inputcommand.js index 5ad4c7d..0435499 100644 --- a/src/inputcommand.js +++ b/src/inputcommand.js @@ -64,7 +64,7 @@ export default class InputCommand extends Command { * @param {String} [options.text=''] Text to be inserted. * @param {module:engine/model/range~Range} [options.range] Range in which the text is inserted. Defaults * to the first range in the current selection. - * @param {module:engine/model/position~Position} [options.resultPosition] Position at which the selection + * @param {module:engine/model/range~Range} [options.resultRange] Range at which the selection * should be placed after the insertion. If not specified, the selection will be placed right after * the inserted text. */ @@ -73,7 +73,7 @@ export default class InputCommand extends Command { const text = options.text || ''; const textInsertions = text.length; const range = options.range || doc.selection.getFirstRange(); - const resultPosition = options.resultPosition; + const resultRange = options.resultRange; doc.enqueueChanges( () => { const isCollapsedRange = range.isCollapsed; @@ -86,8 +86,8 @@ export default class InputCommand extends Command { this._buffer.batch.weakInsert( range.start, text ); - if ( resultPosition ) { - this.editor.data.model.selection.collapse( resultPosition ); + if ( resultRange ) { + this.editor.data.model.selection.setRanges( [ resultRange ] ); } else if ( isCollapsedRange ) { // If range was collapsed just shift the selection by the number of inserted characters. this.editor.data.model.selection.collapse( range.start.getShiftedBy( textInsertions ) ); From ee4c16020760718eaa3c0cc8dd96677d6ec1ce73 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Krzto=C5=84?= Date: Mon, 13 Mar 2017 09:40:26 +0100 Subject: [PATCH 2/7] Tests: Range as InputCommand parameter. --- tests/input.js | 22 ++++++++++++++++++++++ tests/manual/86/1.html | 3 +++ tests/manual/86/1.js | 28 ++++++++++++++++++++++++++++ tests/manual/86/1.md | 5 +++++ 4 files changed, 58 insertions(+) create mode 100644 tests/manual/86/1.html create mode 100644 tests/manual/86/1.js create mode 100644 tests/manual/86/1.md diff --git a/tests/input.js b/tests/input.js index 5666aee..19ca983 100644 --- a/tests/input.js +++ b/tests/input.js @@ -295,6 +295,28 @@ describe( 'Input feature', () => { expect( getViewData( view ) ).to.equal( '

Foo house{}

' ); } ); + it( 'should place non-collapsed selection after changing single character (composition)', () => { + // This test case emulates spellchecker correction. + editor.setData( '

Foo house

' ); + + const viewSelection = new ViewSelection(); + viewSelection.collapse( viewRoot.getChild( 0 ).getChild( 0 ), 8 ); + viewSelection.setFocus( viewRoot.getChild( 0 ).getChild( 0 ), 9 ); + + view.fire( 'mutations', + [ { + type: 'text', + oldText: 'Foo house', + newText: 'Foo housa', + node: viewRoot.getChild( 0 ).getChild( 0 ) + } ], + viewSelection + ); + + expect( getModelData( model ) ).to.equal( 'Foo hous[a]' ); + expect( getViewData( view ) ).to.equal( '

Foo hous{a}

' ); + } ); + it( 'should replace last   with space', () => { model.enqueueChanges( () => { model.selection.setRanges( [ diff --git a/tests/manual/86/1.html b/tests/manual/86/1.html new file mode 100644 index 0000000..c1f5bc8 --- /dev/null +++ b/tests/manual/86/1.html @@ -0,0 +1,3 @@ +
+

This is an editor instance.

+
diff --git a/tests/manual/86/1.js b/tests/manual/86/1.js new file mode 100644 index 0000000..7c7329b --- /dev/null +++ b/tests/manual/86/1.js @@ -0,0 +1,28 @@ +/** + * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved. + * For licensing, see LICENSE.md. + */ + +/* globals console, window, document */ + +import ClassicEditor from '@ckeditor/ckeditor5-editor-classic/src/classic'; +import Enter from '@ckeditor/ckeditor5-enter/src/enter'; +import Typing from '../../../src/typing'; +import Paragraph from '@ckeditor/ckeditor5-paragraph/src/paragraph'; +import Undo from '@ckeditor/ckeditor5-undo/src/undo'; +import { getData } from '@ckeditor/ckeditor5-engine/src/dev-utils/model'; + +window.setInterval( function() { + console.log( getData( window.editor.document ) ); +}, 3000 ); + +ClassicEditor.create( document.querySelector( '#editor' ), { + plugins: [ Enter, Typing, Paragraph, Undo ], + toolbar: [ 'undo', 'redo' ] +} ) + .then( editor => { + window.editor = editor; + } ) + .catch( err => { + console.error( err.stack ); + } ); diff --git a/tests/manual/86/1.md b/tests/manual/86/1.md new file mode 100644 index 0000000..db30ffe --- /dev/null +++ b/tests/manual/86/1.md @@ -0,0 +1,5 @@ +## Typing - MacOS accent balloon + +It is possible to navigate with arrow keys inside MacOS balloon panel and insert a selected accent +(long "a" press to activate accent balloon). + From 54fd2a3c288bb598a6dca4e2ca207b9a36cbe42c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Krzto=C5=84?= Date: Mon, 13 Mar 2017 09:41:56 +0100 Subject: [PATCH 3/7] Indentation fix. --- tests/manual/86/1.js | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/tests/manual/86/1.js b/tests/manual/86/1.js index 7c7329b..4b57484 100644 --- a/tests/manual/86/1.js +++ b/tests/manual/86/1.js @@ -20,9 +20,9 @@ ClassicEditor.create( document.querySelector( '#editor' ), { plugins: [ Enter, Typing, Paragraph, Undo ], toolbar: [ 'undo', 'redo' ] } ) - .then( editor => { - window.editor = editor; - } ) - .catch( err => { - console.error( err.stack ); - } ); +.then( editor => { + window.editor = editor; +} ) +.catch( err => { + console.error( err.stack ); +} ); From 45fc341f53d9766d708793457eeaf20de2915f66 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Krzto=C5=84?= Date: Mon, 13 Mar 2017 09:52:19 +0100 Subject: [PATCH 4/7] Tests: updated test description for Safari. --- tests/manual/spellchecking.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/tests/manual/spellchecking.md b/tests/manual/spellchecking.md index cd5556d..6be0fce 100644 --- a/tests/manual/spellchecking.md +++ b/tests/manual/spellchecking.md @@ -4,5 +4,4 @@ Try to correct all misspelled words using native spell checking mechanism in the * Words should be corrected and selection placed after corrected word. -_In Safari selection is placed at the beginning of the corrected word -(this is a known issue [ckeditor5-typing/#54](https://github.com/ckeditor/ckeditor5-typing/issues/54))_. +_In Safari selection contains whole corrected word (same as in native contenteditable)_. From 1a737c6d5e04cb2e5a1d933a747e31a85a42c7be Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Krzto=C5=84?= Date: Mon, 13 Mar 2017 15:12:06 +0100 Subject: [PATCH 5/7] Tests: Use essentials preset in manual tests. --- package.json | 1 + tests/manual/20/1.js | 6 ++---- tests/manual/21/1.js | 6 ++---- tests/manual/82/1.js | 6 ++---- tests/manual/86/1.js | 6 ++---- tests/manual/delete.js | 6 ++---- tests/manual/input.js | 6 ++---- tests/manual/rtl.js | 6 ++---- tests/manual/selection.js | 6 ++---- tests/manual/spellchecking.js | 6 ++---- 10 files changed, 19 insertions(+), 36 deletions(-) diff --git a/package.json b/package.json index 0b21c78..8c13c85 100644 --- a/package.json +++ b/package.json @@ -16,6 +16,7 @@ "@ckeditor/ckeditor5-heading": "^0.8.0", "@ckeditor/ckeditor5-paragraph": "^0.6.1", "@ckeditor/ckeditor5-undo": "^0.7.1", + "@ckeditor/ckeditor5-presets": "^0.1.1", "gulp": "^3.9.0", "guppy-pre-commit": "^0.4.0" }, diff --git a/tests/manual/20/1.js b/tests/manual/20/1.js index d27220d..9a4bd20 100644 --- a/tests/manual/20/1.js +++ b/tests/manual/20/1.js @@ -6,16 +6,14 @@ /* globals console, window, document */ import ClassicEditor from '@ckeditor/ckeditor5-editor-classic/src/classic'; -import Enter from '@ckeditor/ckeditor5-enter/src/enter'; -import Typing from '../../../src/typing'; import Heading from '@ckeditor/ckeditor5-heading/src/heading'; import Paragraph from '@ckeditor/ckeditor5-paragraph/src/paragraph'; -import Undo from '@ckeditor/ckeditor5-undo/src/undo'; import Bold from '@ckeditor/ckeditor5-basic-styles/src/bold'; import Italic from '@ckeditor/ckeditor5-basic-styles/src/italic'; +import EssentialsPreset from '@ckeditor/ckeditor5-presets/src/essentials'; ClassicEditor.create( document.querySelector( '#editor' ), { - plugins: [ Enter, Typing, Paragraph, Undo, Bold, Italic, Heading ], + plugins: [ EssentialsPreset, Paragraph, Bold, Italic, Heading ], toolbar: [ 'headings', 'bold', 'italic', 'undo', 'redo' ] } ) .then( editor => { diff --git a/tests/manual/21/1.js b/tests/manual/21/1.js index d27220d..9a4bd20 100644 --- a/tests/manual/21/1.js +++ b/tests/manual/21/1.js @@ -6,16 +6,14 @@ /* globals console, window, document */ import ClassicEditor from '@ckeditor/ckeditor5-editor-classic/src/classic'; -import Enter from '@ckeditor/ckeditor5-enter/src/enter'; -import Typing from '../../../src/typing'; import Heading from '@ckeditor/ckeditor5-heading/src/heading'; import Paragraph from '@ckeditor/ckeditor5-paragraph/src/paragraph'; -import Undo from '@ckeditor/ckeditor5-undo/src/undo'; import Bold from '@ckeditor/ckeditor5-basic-styles/src/bold'; import Italic from '@ckeditor/ckeditor5-basic-styles/src/italic'; +import EssentialsPreset from '@ckeditor/ckeditor5-presets/src/essentials'; ClassicEditor.create( document.querySelector( '#editor' ), { - plugins: [ Enter, Typing, Paragraph, Undo, Bold, Italic, Heading ], + plugins: [ EssentialsPreset, Paragraph, Bold, Italic, Heading ], toolbar: [ 'headings', 'bold', 'italic', 'undo', 'redo' ] } ) .then( editor => { diff --git a/tests/manual/82/1.js b/tests/manual/82/1.js index 7a6315f..400c037 100644 --- a/tests/manual/82/1.js +++ b/tests/manual/82/1.js @@ -6,11 +6,9 @@ /* globals console, window, document */ import ClassicEditor from '@ckeditor/ckeditor5-editor-classic/src/classic'; -import Enter from '@ckeditor/ckeditor5-enter/src/enter'; -import Typing from '../../../src/typing'; import Heading from '@ckeditor/ckeditor5-heading/src/heading'; import Paragraph from '@ckeditor/ckeditor5-paragraph/src/paragraph'; -import Undo from '@ckeditor/ckeditor5-undo/src/undo'; +import EssentialsPreset from '@ckeditor/ckeditor5-presets/src/essentials'; import { getData } from '@ckeditor/ckeditor5-engine/src/dev-utils/model'; window.setInterval( function() { @@ -18,7 +16,7 @@ window.setInterval( function() { }, 3000 ); ClassicEditor.create( document.querySelector( '#editor' ), { - plugins: [ Enter, Typing, Paragraph, Undo, Heading ], + plugins: [ EssentialsPreset, Paragraph, Heading ], toolbar: [ 'headings', 'undo', 'redo' ] } ) .then( editor => { diff --git a/tests/manual/86/1.js b/tests/manual/86/1.js index 4b57484..4bdd4bd 100644 --- a/tests/manual/86/1.js +++ b/tests/manual/86/1.js @@ -6,10 +6,8 @@ /* globals console, window, document */ import ClassicEditor from '@ckeditor/ckeditor5-editor-classic/src/classic'; -import Enter from '@ckeditor/ckeditor5-enter/src/enter'; -import Typing from '../../../src/typing'; +import EssentialsPreset from '@ckeditor/ckeditor5-presets/src/essentials'; import Paragraph from '@ckeditor/ckeditor5-paragraph/src/paragraph'; -import Undo from '@ckeditor/ckeditor5-undo/src/undo'; import { getData } from '@ckeditor/ckeditor5-engine/src/dev-utils/model'; window.setInterval( function() { @@ -17,7 +15,7 @@ window.setInterval( function() { }, 3000 ); ClassicEditor.create( document.querySelector( '#editor' ), { - plugins: [ Enter, Typing, Paragraph, Undo ], + plugins: [ EssentialsPreset, Paragraph ], toolbar: [ 'undo', 'redo' ] } ) .then( editor => { diff --git a/tests/manual/delete.js b/tests/manual/delete.js index 4be75ae..6b0c15b 100644 --- a/tests/manual/delete.js +++ b/tests/manual/delete.js @@ -6,13 +6,11 @@ /* globals console, window, document */ import ClassicEditor from '@ckeditor/ckeditor5-editor-classic/src/classic'; -import Enter from '@ckeditor/ckeditor5-enter/src/enter'; -import Typing from '../../src/typing'; import Heading from '@ckeditor/ckeditor5-heading/src/heading'; import Paragraph from '@ckeditor/ckeditor5-paragraph/src/paragraph'; -import Undo from '@ckeditor/ckeditor5-undo/src/undo'; import Bold from '@ckeditor/ckeditor5-basic-styles/src/bold'; import Italic from '@ckeditor/ckeditor5-basic-styles/src/italic'; +import EssentialsPreset from '@ckeditor/ckeditor5-presets/src/essentials'; import { getData } from '@ckeditor/ckeditor5-engine/src/dev-utils/model'; window.getData = getData; @@ -22,7 +20,7 @@ window.setInterval( function() { }, 3000 ); ClassicEditor.create( document.querySelector( '#editor' ), { - plugins: [ Enter, Typing, Paragraph, Undo, Bold, Italic, Heading ], + plugins: [ EssentialsPreset, Paragraph, Bold, Italic, Heading ], toolbar: [ 'headings', 'bold', 'italic', 'undo', 'redo' ] } ) .then( editor => { diff --git a/tests/manual/input.js b/tests/manual/input.js index 587037c..279c55a 100644 --- a/tests/manual/input.js +++ b/tests/manual/input.js @@ -6,13 +6,11 @@ /* globals console, window, document */ import ClassicEditor from '@ckeditor/ckeditor5-editor-classic/src/classic'; -import Enter from '@ckeditor/ckeditor5-enter/src/enter'; -import Typing from '../../src/typing'; import Heading from '@ckeditor/ckeditor5-heading/src/heading'; import Paragraph from '@ckeditor/ckeditor5-paragraph/src/paragraph'; -import Undo from '@ckeditor/ckeditor5-undo/src/undo'; import Bold from '@ckeditor/ckeditor5-basic-styles/src/bold'; import Italic from '@ckeditor/ckeditor5-basic-styles/src/italic'; +import EssentialsPreset from '@ckeditor/ckeditor5-presets/src/essentials'; import { getData } from '@ckeditor/ckeditor5-engine/src/dev-utils/model'; window.setInterval( function() { @@ -20,7 +18,7 @@ window.setInterval( function() { }, 3000 ); ClassicEditor.create( document.querySelector( '#editor' ), { - plugins: [ Enter, Typing, Paragraph, Undo, Bold, Italic, Heading ], + plugins: [ EssentialsPreset, Paragraph, Bold, Italic, Heading ], toolbar: [ 'headings', 'bold', 'italic', 'undo', 'redo' ] } ) .then( editor => { diff --git a/tests/manual/rtl.js b/tests/manual/rtl.js index a78440b..ab72d2c 100644 --- a/tests/manual/rtl.js +++ b/tests/manual/rtl.js @@ -6,17 +6,15 @@ /* globals console, window, document */ import ClassicEditor from '@ckeditor/ckeditor5-editor-classic/src/classic'; -import Enter from '@ckeditor/ckeditor5-enter/src/enter'; -import Typing from '../../src/typing'; import Heading from '@ckeditor/ckeditor5-heading/src/heading'; import Paragraph from '@ckeditor/ckeditor5-paragraph/src/paragraph'; -import Undo from '@ckeditor/ckeditor5-undo/src/undo'; import Bold from '@ckeditor/ckeditor5-basic-styles/src/bold'; import Italic from '@ckeditor/ckeditor5-basic-styles/src/italic'; +import EssentialsPreset from '@ckeditor/ckeditor5-presets/src/essentials'; import { getData } from '@ckeditor/ckeditor5-engine/src/dev-utils/model'; const config = { - plugins: [ Enter, Typing, Paragraph, Undo, Bold, Italic, Heading ], + plugins: [ EssentialsPreset, Paragraph, Bold, Italic, Heading ], toolbar: [ 'headings', 'bold', 'italic', 'undo', 'redo' ] }; diff --git a/tests/manual/selection.js b/tests/manual/selection.js index 81b6adc..0d43e07 100644 --- a/tests/manual/selection.js +++ b/tests/manual/selection.js @@ -6,14 +6,12 @@ /* globals console, document, window */ import ClassicEditor from '@ckeditor/ckeditor5-editor-classic/src/classic'; -import Enter from '@ckeditor/ckeditor5-enter/src/enter'; -import Typing from '../../src/typing'; import Paragraph from '@ckeditor/ckeditor5-paragraph/src/paragraph'; import Bold from '@ckeditor/ckeditor5-basic-styles/src/bold'; -import Undo from '@ckeditor/ckeditor5-undo/src/undo'; +import EssentialsPreset from '@ckeditor/ckeditor5-presets/src/essentials'; ClassicEditor.create( document.querySelector( '#editor' ), { - plugins: [ Enter, Typing, Paragraph, Undo, Bold ], + plugins: [ EssentialsPreset, Paragraph, Bold ], toolbar: [ 'bold' ] } ) .then( editor => { diff --git a/tests/manual/spellchecking.js b/tests/manual/spellchecking.js index ecfab27..feb7f15 100644 --- a/tests/manual/spellchecking.js +++ b/tests/manual/spellchecking.js @@ -6,13 +6,11 @@ /* globals console, window, document */ import ClassicEditor from '@ckeditor/ckeditor5-editor-classic/src/classic'; -import Enter from '@ckeditor/ckeditor5-enter/src/enter'; -import Typing from '../../src/typing'; import Heading from '@ckeditor/ckeditor5-heading/src/heading'; import Paragraph from '@ckeditor/ckeditor5-paragraph/src/paragraph'; -import Undo from '@ckeditor/ckeditor5-undo/src/undo'; import Bold from '@ckeditor/ckeditor5-basic-styles/src/bold'; import Italic from '@ckeditor/ckeditor5-basic-styles/src/italic'; +import EssentialsPreset from '@ckeditor/ckeditor5-presets/src/essentials'; import { getData } from '@ckeditor/ckeditor5-engine/src/dev-utils/model'; window.setInterval( function() { @@ -20,7 +18,7 @@ window.setInterval( function() { }, 3000 ); ClassicEditor.create( document.querySelector( '#editor' ), { - plugins: [ Enter, Typing, Paragraph, Undo, Bold, Italic, Heading ], + plugins: [ EssentialsPreset, Paragraph, Bold, Italic, Heading ], toolbar: [ 'headings', 'bold', 'italic', 'undo', 'redo' ] } ) .then( editor => { From 17e0d66b671245904666444dca93accfaa47a817 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Krzto=C5=84?= Date: Mon, 13 Mar 2017 15:26:15 +0100 Subject: [PATCH 6/7] Tests: `resultRange` unit tests. --- tests/inputcommand.js | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/tests/inputcommand.js b/tests/inputcommand.js index cc1ec11..939f463 100644 --- a/tests/inputcommand.js +++ b/tests/inputcommand.js @@ -7,6 +7,8 @@ import VirtualTestEditor from '@ckeditor/ckeditor5-core/tests/_utils/virtualtest import ModelTestEditor from '@ckeditor/ckeditor5-core/tests/_utils/modeltesteditor'; import testUtils from '@ckeditor/ckeditor5-core/tests/_utils/utils'; import { getData, setData } from '@ckeditor/ckeditor5-engine/src/dev-utils/model'; +import Range from '@ckeditor/ckeditor5-engine/src/model/range'; +import Position from '@ckeditor/ckeditor5-engine/src/model/position'; import InputCommand from '../src/inputcommand'; import ChangeBuffer from '../src/changebuffer'; import Input from '../src/input'; @@ -168,6 +170,30 @@ describe( 'InputCommand', () => { expect( buffer.size ).to.be.equal( 0 ); } ); + it( 'should set selection according to passed resultRange (collapsed)', () => { + setData( doc, '

[foo]bar

' ); + + editor.execute( 'input', { + text: 'new', + resultRange: new Range( new Position( doc.getRoot(), [ 0, 5 ] ) ) + } ); + + expect( getData( doc, { selection: true } ) ).to.be.equal( '

newba[]r

' ); + expect( buffer.size ).to.be.equal( 3 ); + } ); + + it( 'should set selection according to passed resultRange (non-collapsed)', () => { + setData( doc, '

[foo]bar

' ); + + editor.execute( 'input', { + text: 'new', + resultRange: new Range( new Position( doc.getRoot(), [ 0, 3 ] ), new Position( doc.getRoot(), [ 0, 6 ] ) ) + } ); + + expect( getData( doc, { selection: true } ) ).to.be.equal( '

new[bar]

' ); + expect( buffer.size ).to.be.equal( 3 ); + } ); + it( 'only removes content when no text given (with default non-collapsed range)', () => { setData( doc, '

[fo]obar

' ); From a7c56f8b8b9d15a31648af62e85e8d48542d8eff Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Krzto=C5=84?= Date: Mon, 13 Mar 2017 15:30:33 +0100 Subject: [PATCH 7/7] Tests: redundant comment removed. --- tests/input.js | 1 - 1 file changed, 1 deletion(-) diff --git a/tests/input.js b/tests/input.js index 19ca983..050277e 100644 --- a/tests/input.js +++ b/tests/input.js @@ -296,7 +296,6 @@ describe( 'Input feature', () => { } ); it( 'should place non-collapsed selection after changing single character (composition)', () => { - // This test case emulates spellchecker correction. editor.setData( '

Foo house

' ); const viewSelection = new ViewSelection();