diff --git a/packages/ckeditor5-restricted-editing/package.json b/packages/ckeditor5-restricted-editing/package.json index 4de6534fafe..336d22bc51c 100644 --- a/packages/ckeditor5-restricted-editing/package.json +++ b/packages/ckeditor5-restricted-editing/package.json @@ -18,10 +18,13 @@ "@ckeditor/ckeditor5-basic-styles": "41.2.1", "@ckeditor/ckeditor5-block-quote": "41.2.1", "@ckeditor/ckeditor5-clipboard": "41.2.1", + "@ckeditor/ckeditor5-cloud-services": "41.2.1", "@ckeditor/ckeditor5-core": "41.2.1", "@ckeditor/ckeditor5-dev-utils": "^39.0.0", + "@ckeditor/ckeditor5-easy-image": "41.2.1", "@ckeditor/ckeditor5-editor-classic": "41.2.1", "@ckeditor/ckeditor5-engine": "41.2.1", + "@ckeditor/ckeditor5-image": "41.2.1", "@ckeditor/ckeditor5-link": "41.2.1", "@ckeditor/ckeditor5-paragraph": "41.2.1", "@ckeditor/ckeditor5-table": "41.2.1", diff --git a/packages/ckeditor5-restricted-editing/src/restrictededitingmode/converters.ts b/packages/ckeditor5-restricted-editing/src/restrictededitingmode/converters.ts index 6ff30d2f3b1..41cd0bd5ca7 100644 --- a/packages/ckeditor5-restricted-editing/src/restrictededitingmode/converters.ts +++ b/packages/ckeditor5-restricted-editing/src/restrictededitingmode/converters.ts @@ -106,9 +106,10 @@ export function extendMarkerOnTypingPostFixer( editor: Editor ): ModelPostFixer // This post-fixer shouldn't be necessary after https://github.com/ckeditor/ckeditor5/issues/5778. return writer => { let changeApplied = false; + const schema = editor.model.schema; for ( const change of editor.model.document.differ.getChanges() ) { - if ( change.type == 'insert' && change.name == '$text' ) { + if ( change.type == 'insert' && schema.checkChild( '$block', change.name ) ) { changeApplied = _tryExtendMarkerStart( editor, change.position, change.length, writer ) || changeApplied; changeApplied = _tryExtendMarkedEnd( editor, change.position, change.length, writer ) || changeApplied; } diff --git a/packages/ckeditor5-restricted-editing/tests/manual/restrictedediting.js b/packages/ckeditor5-restricted-editing/tests/manual/restrictedediting.js index 88b181de9a5..fc69ef959ba 100644 --- a/packages/ckeditor5-restricted-editing/tests/manual/restrictedediting.js +++ b/packages/ckeditor5-restricted-editing/tests/manual/restrictedediting.js @@ -8,10 +8,16 @@ import ClassicEditor from '@ckeditor/ckeditor5-editor-classic/src/classiceditor.js'; import ArticlePluginSet from '@ckeditor/ckeditor5-core/tests/_utils/articlepluginset.js'; import Table from '@ckeditor/ckeditor5-table/src/table.js'; +import EasyImage from '@ckeditor/ckeditor5-easy-image/src/easyimage.js'; +import ImageUpload from '@ckeditor/ckeditor5-image/src/imageupload.js'; +import CloudServices from '@ckeditor/ckeditor5-cloud-services/src/cloudservices.js'; +import ImageInsert from '@ckeditor/ckeditor5-image/src/imageinsert.js'; +import TableToolbar from '@ckeditor/ckeditor5-table/src/tabletoolbar.js'; import StandardEditingMode from '../../src/standardeditingmode.js'; import RestrictedEditingMode from '../../src/restrictededitingmode.js'; -import TableToolbar from '@ckeditor/ckeditor5-table/src/tabletoolbar.js'; + +import { CS_CONFIG } from '@ckeditor/ckeditor5-cloud-services/tests/_utils/cloud-services-config.js'; const restrictedModeButton = document.getElementById( 'mode-restricted' ); const standardModeButton = document.getElementById( 'mode-standard' ); @@ -35,14 +41,17 @@ async function startMode( selectedMode ) { async function startStandardEditingMode() { await reloadEditor( { - plugins: [ ArticlePluginSet, Table, StandardEditingMode ], + plugins: [ ArticlePluginSet, Table, EasyImage, ImageInsert, ImageUpload, CloudServices, StandardEditingMode ], toolbar: [ 'heading', '|', 'bold', 'italic', 'link', '|', - 'bulletedList', 'numberedList', 'blockQuote', 'insertTable', '|', + 'bulletedList', 'numberedList', 'blockQuote', 'insertTable', 'insertImage', '|', 'restrictedEditingException', '|', 'undo', 'redo' ], image: { - toolbar: [ 'imageStyle:inline', 'imageStyle:block', 'imageStyle:wrapText', '|', 'imageTextAlternative' ] + toolbar: [ 'imageStyle:inline', 'imageStyle:block', 'imageStyle:wrapText', '|', 'imageTextAlternative' ], + insert: { + type: 'auto' + } }, table: { contentToolbar: [ @@ -51,6 +60,7 @@ async function startStandardEditingMode() { 'mergeTableCells' ] }, + cloudServices: CS_CONFIG, updateSourceElementOnDestroy: true } ); } @@ -74,12 +84,23 @@ function MyPlugin( editor ) { async function startRestrictedEditingMode() { await reloadEditor( { - plugins: [ ArticlePluginSet, Table, TableToolbar, RestrictedEditingMode, MyPlugin ], - toolbar: [ 'bold', 'italic', 'link', '|', 'restrictedEditing', '|', 'undo', 'redo' ], + plugins: [ + ArticlePluginSet, Table, TableToolbar, EasyImage, ImageInsert, ImageUpload, CloudServices, RestrictedEditingMode, MyPlugin + ], + toolbar: [ 'bold', 'italic', 'link', 'insertImage', '|', 'restrictedEditing', '|', 'undo', 'redo' ], + image: { + insert: { + type: 'inline' + } + }, table: { contentToolbar: [ 'tableColumn', 'tableRow', 'mergeTableCells' ], tableToolbar: [ 'bold', 'italic' ] }, + restrictedEditing: { + allowedCommands: [ 'imageInsert', 'imageUpload' ] + }, + cloudServices: CS_CONFIG, updateSourceElementOnDestroy: true } ); } diff --git a/packages/ckeditor5-restricted-editing/tests/restrictededitingmodeediting.js b/packages/ckeditor5-restricted-editing/tests/restrictededitingmodeediting.js index 4779c1e1898..2b79e9b740f 100644 --- a/packages/ckeditor5-restricted-editing/tests/restrictededitingmodeediting.js +++ b/packages/ckeditor5-restricted-editing/tests/restrictededitingmodeediting.js @@ -14,6 +14,9 @@ import BoldEditing from '@ckeditor/ckeditor5-basic-styles/src/bold/boldediting.j import StrikethroughEditing from '@ckeditor/ckeditor5-basic-styles/src/strikethrough/strikethroughediting.js'; import LinkEditing from '@ckeditor/ckeditor5-link/src/linkediting.js'; import Typing from '@ckeditor/ckeditor5-typing/src/typing.js'; +import ImageInlineEditing from '@ckeditor/ckeditor5-image/src/image/imageinlineediting.js'; +import InsertImageCommand from '@ckeditor/ckeditor5-image/src/image/insertimagecommand.js'; + import ClipboardPipeline from '@ckeditor/ckeditor5-clipboard/src/clipboardpipeline.js'; import RestrictedEditingModeEditing from './../src/restrictededitingmodeediting.js'; @@ -378,7 +381,9 @@ describe( 'RestrictedEditingModeEditing', () => { describe( 'editing behavior', () => { beforeEach( async () => { - editor = await VirtualTestEditor.create( { plugins: [ Paragraph, Typing, RestrictedEditingModeEditing, ClipboardPipeline ] } ); + editor = await VirtualTestEditor.create( { plugins: [ + Paragraph, Typing, RestrictedEditingModeEditing, ClipboardPipeline, ImageInlineEditing + ] } ); model = editor.model; } ); @@ -452,7 +457,7 @@ describe( 'RestrictedEditingModeEditing', () => { expect( getModelData( model ) ).to.equalMarkup( 'foo bX[]ar baz' ); } ); - it( 'should extend maker when typing on the marker boundary (end)', () => { + it( 'should extend marker when typing on the marker boundary (end)', () => { setModelData( model, 'foo bar[] baz' ); const firstParagraph = model.document.getRoot().getChild( 0 ); @@ -476,6 +481,68 @@ describe( 'RestrictedEditingModeEditing', () => { expect( markerRange.isEqual( expectedRange ) ).to.be.true; } ); + it( 'should extend marker when inserting inline image on the marker boundary (end)', () => { + setModelData( model, 'foo bar[] baz' ); + const imgSrc = 'foo/bar.jpg'; + const firstParagraph = model.document.getRoot().getChild( 0 ); + // We don't use `editor.execute( ... )` because it requires adding Image plugin into VirtualTestEditor, + // so it's impossible because it doesn't has 'ui' which Image package requires. So we are simply using + // `new InsertImageCommand()` command. + const command = new InsertImageCommand( editor ); + + model.change( writer => { + writer.addMarker( 'restrictedEditingException:1', { + range: writer.createRange( writer.createPositionAt( firstParagraph, 4 ), writer.createPositionAt( firstParagraph, 7 ) ), + usingOperation: true, + affectsData: true + } ); + } ); + + command.execute( { source: imgSrc } ); + + expect( getModelData( model ) ).to.equalMarkup( + 'foo bar[] baz' + ); + const markerRange = editor.model.markers.get( 'restrictedEditingException:1' ).getRange(); + const expectedRange = model.createRange( + model.createPositionAt( firstParagraph, 4 ), + model.createPositionAt( firstParagraph, 8 ) + ); + + expect( markerRange.isEqual( expectedRange ) ).to.be.true; + } ); + + it( 'should extend marker when inserting inline image on the marker boundary (start)', () => { + setModelData( model, 'foo []bar baz' ); + const imgSrc = 'foo/bar.jpg'; + const firstParagraph = model.document.getRoot().getChild( 0 ); + // We don't use `editor.execute( ... )` because it requires adding Image plugin into VirtualTestEditor, + // so it's impossible because it doesn't has 'ui' which Image package requires. So we are simply using + // `new InsertImageCommand()` command. + const command = new InsertImageCommand( editor ); + + model.change( writer => { + writer.addMarker( 'restrictedEditingException:1', { + range: writer.createRange( writer.createPositionAt( firstParagraph, 4 ), writer.createPositionAt( firstParagraph, 7 ) ), + usingOperation: true, + affectsData: true + } ); + } ); + + command.execute( { source: imgSrc } ); + + expect( getModelData( model ) ).to.equalMarkup( + 'foo []bar baz' + ); + const markerRange = editor.model.markers.get( 'restrictedEditingException:1' ).getRange(); + const expectedRange = model.createRange( + model.createPositionAt( firstParagraph, 4 ), + model.createPositionAt( firstParagraph, 8 ) + ); + + expect( markerRange.isEqual( expectedRange ) ).to.be.true; + } ); + it( 'should extend marker when typing on the marker boundary (start)', () => { setModelData( model, 'foo []bar baz' ); const firstParagraph = model.document.getRoot().getChild( 0 );