/** * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved. * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license */ /* global document */ import CodeBlockEditing from '../src/codeblockediting'; import CodeBlockCommand from '../src/codeblockcommand'; import AlignmentEditing from '@ckeditor/ckeditor5-alignment/src/alignmentediting'; import BoldEditing from '@ckeditor/ckeditor5-basic-styles/src/bold/boldediting'; import Enter from '@ckeditor/ckeditor5-enter/src/enter'; import ShiftEnter from '@ckeditor/ckeditor5-enter/src/shiftenter'; import Paragraph from '@ckeditor/ckeditor5-paragraph/src/paragraph'; import Undo from '@ckeditor/ckeditor5-undo/src/undo'; import DomEventData from '@ckeditor/ckeditor5-engine/src/view/observer/domeventdata'; import ClassicTestEditor from '@ckeditor/ckeditor5-core/tests/_utils/classictesteditor'; import { getData as getModelData, setData as setModelData } from '@ckeditor/ckeditor5-engine/src/dev-utils/model'; import { getData as getViewData } from '@ckeditor/ckeditor5-engine/src/dev-utils/view'; import { _clear as clearTranslations, add as addTranslations } from '@ckeditor/ckeditor5-utils/src/translation-service'; describe( 'CodeBlockEditing', () => { let editor, element, model, view, viewDoc; before( () => { addTranslations( 'en', { 'Plain text': 'Plain text' } ); addTranslations( 'pl', { 'Plain text': 'Zwykły tekst' } ); } ); after( () => { clearTranslations(); } ); beforeEach( () => { element = document.createElement( 'div' ); document.body.appendChild( element ); return ClassicTestEditor .create( element, { language: 'en', plugins: [ CodeBlockEditing, AlignmentEditing, BoldEditing, Enter, Paragraph, Undo ] } ) .then( newEditor => { editor = newEditor; model = editor.model; view = editor.editing.view; viewDoc = view.document; } ); } ); afterEach( () => { return editor.destroy().then( () => element.remove() ); } ); it( 'defines plugin name', () => { expect( CodeBlockEditing.pluginName ).to.equal( 'CodeBlockEditing' ); } ); it( 'defines plugin dependencies', () => { expect( CodeBlockEditing.requires ).to.have.members( [ ShiftEnter ] ); } ); describe( 'config', () => { describe( 'languages', () => { describe( 'default value', () => { it( 'should be set', () => { expect( editor.config.get( 'codeBlock.languages' ) ).to.deep.equal( [ { class: 'plaintext', label: 'Plain text' }, { class: 'c', label: 'C' }, { class: 'cs', label: 'C#' }, { class: 'cpp', label: 'C++' }, { class: 'css', label: 'CSS' }, { class: 'diff', label: 'Diff' }, { class: 'xml', label: 'HTML/XML' }, { class: 'java', label: 'Java' }, { class: 'javascript', label: 'JavaScript' }, { class: 'php', label: 'PHP' }, { class: 'python', label: 'Python' }, { class: 'ruby', label: 'Ruby' }, { class: 'typescript', label: 'TypeScript' } ] ); } ); } ); it( 'should be recognized when loading data', () => { return ClassicTestEditor.create( '
bar' +
'baz',
{
plugins: [ CodeBlockEditing ],
codeBlock: {
languages: [
{ class: 'foo', label: 'Foo' },
{ class: 'bar', label: 'Bar' },
]
}
} )
.then( editor => {
model = editor.model;
expect( getModelData( model ) ).to.equal(
'bar', {
plugins: [ CodeBlockEditing ],
codeBlock: {
languages: [
{ class: 'foo', label: 'Foo' },
{ class: 'bar', label: 'Bar' }
]
}
} )
.then( editor => {
model = editor.model;
expect( getModelData( model ) ).to.equal( 'bar', {
plugins: [ CodeBlockEditing ],
codeBlock: {
languages: [
{ class: 'foo', label: 'Foo' },
{ class: 'bar', label: 'Bar' }
]
}
} )
.then( editor => {
model = editor.model;
expect( getModelData( model ) ).to.equal( '[]' );
} );
it( 'should convert non-empty codeBlock to pre tag', () => {
setModelData( model, '{}Foo' );
} );
it( 'should convert codeBlock with softBreaks to pre tag #1', () => {
setModelData( model,
'' +
'{}Foo
Bar
Biz' +
'' );
} );
it( 'should convert codeBlock with softBreaks to pre tag #2', () => {
setModelData( model,
'' +
'[]
Foo
' +
'' );
} );
it( 'should use localized "Plain text" label', () => {
const element = document.createElement( 'div' );
document.body.appendChild( element );
return ClassicTestEditor
.create( element, {
language: 'pl',
plugins: [ CodeBlockEditing, AlignmentEditing, BoldEditing, Enter, Paragraph ]
} )
.then( newEditor => {
const editor = newEditor;
const model = editor.model;
const view = editor.editing.view;
setModelData( model,
'' +
'{}foo' +
'' );
element.remove();
return editor.destroy();
} );
} );
} );
describe( 'data pipeline m -> v conversion ', () => {
it( 'should convert empty codeBlock to empty pre tag', () => {
setModelData( model, ' ' );
} );
it( 'should convert non-empty codeBlock to pre tag', () => {
setModelData( model, 'Foo' );
} );
it( 'should convert codeBlock with softBreaks to pre tag #1', () => {
setModelData( model,
'Foo\nBar\nBizA
B
\n\nFoo\n\n' );
} );
it( 'should convert codeBlock with html content', () => {
setModelData( model, 'Foo
' +
'<div><p>Foo</p></div>' +
'' );
} );
it( 'should be overridable', () => {
editor.data.downcastDispatcher.on( 'insert:codeBlock', ( evt, data, api ) => {
const targetViewPosition = api.mapper.toViewPosition( model.createPositionBefore( data.item ) );
const code = api.writer.createContainerElement( 'code' );
api.consumable.consume( data.item, 'insert' );
api.writer.insert( targetViewPosition, code );
api.mapper.bindElements( data.item, code );
}, { priority: 'high' } );
editor.data.downcastDispatcher.on( 'insert:softBreak', ( evt, data, api ) => {
const position = api.mapper.toViewPosition( model.createPositionBefore( data.item ) );
api.consumable.consume( data.item, 'insert' );
api.writer.insert( position, api.writer.createText( '\n' ) );
}, { priority: 'highest' } );
setModelData( model, 'Foo\nBar' );
} );
} );
describe( 'data pipeline v -> m conversion ', () => {
it( 'should not convert empty pre tag to code block', () => {
editor.setData( '' );
expect( getModelData( model ) ).to.equal( '' ); expect( getModelData( model ) ).to.equal( '
' );
expect( getModelData( model ) ).to.equal( 'foo\nbar' );
expect( getModelData( model ) ).to.equal(
'\n\nfoo\n\n' );
expect( getModelData( model ) ).to.equal(
'Foo
\nBar
' );
expect( getModelData( model ) ).to.equal(
'Foo
' + 'Bar
' + 'Foo
Bar
Biz
' );
expect( getModelData( model ) ).to.equal( 'Foo
Bar
Biz
<div><p>Foo</p></div>' );
expect( getModelData( model ) ).to.equal( 'Foo
Foo Bar' );
expect( getModelData( model ) ).to.equal( 'foo
xbar' );
// Note: The empty foobar' );
expect( getModelData( model ) ).to.equal(
'foo
bar` );
// Note: The empty foo' } );
expect( getModelData( model, { rootName: 'title', withoutSelection: true } ) ).to.equal( '' );
} );
} );
describe( 'clipboard integration', () => {
it( 'should not intercept input when selection anchored outside any code block', () => {
setModelData( model, '