Skip to content

Commit

Permalink
Merge 4f779d0 into 0765026
Browse files Browse the repository at this point in the history
  • Loading branch information
pomek committed Apr 7, 2022
2 parents 0765026 + 4f779d0 commit 00f695e
Show file tree
Hide file tree
Showing 5 changed files with 173 additions and 37 deletions.
8 changes: 5 additions & 3 deletions sample/index.html
Expand Up @@ -36,6 +36,8 @@ <h1>CKEditor 5 – React Component – development sample</h1>
const readOnlyButton = document.getElementById( 'readOnly' );
const simulateErrorButton = document.getElementById( 'simulateError' );

const SAMPLE_READ_ONLY_LOCK_ID = 'Integration Sample';

class App extends React.Component {
constructor( props ) {
super( props );
Expand Down Expand Up @@ -82,12 +84,12 @@ <h1>CKEditor 5 – React Component – development sample</h1>
} );

editor.ui.view.listenTo( readOnlyButton, 'click', () => {
editor.isReadOnly = !editor.isReadOnly;
editor.enableReadOnlyMode( SAMPLE_READ_ONLY_LOCK_ID, !editor.isReadOnly );

if ( editor.isReadOnly ) {
this.innerText = 'Switch to editable mode';
readOnlyButton.innerText = 'Switch to editable mode';
} else {
this.innerText = 'Switch to read-only mode';
readOnlyButton.innerText = 'Switch to read-only mode';
}
} );
},
Expand Down
25 changes: 22 additions & 3 deletions src/ckeditor.jsx
Expand Up @@ -3,13 +3,17 @@
* For licensing, see LICENSE.md.
*/

/* globals window */

import React from 'react';
import PropTypes from 'prop-types';
import EditorWatchdog from '@ckeditor/ckeditor5-watchdog/src/editorwatchdog';
import uid from '@ckeditor/ckeditor5-utils/src/uid';
import { ContextWatchdogContext } from './ckeditorcontext.jsx';
import ContextWatchdog from '@ckeditor/ckeditor5-watchdog/src/contextwatchdog';

const REACT_INTEGRATION_READ_ONLY_LOCK_ID = 'Lock from React integration (@ckeditor/ckeditor5-react)';

export default class CKEditor extends React.Component {
constructor( props ) {
super( props );
Expand All @@ -24,6 +28,21 @@ export default class CKEditor extends React.Component {
* @type {module:watchdog/watchdog~Watchdog|EditorWatchdogAdapter}
*/
this.watchdog = null;

const { CKEDITOR_VERSION } = window;

// Starting from v34.0.0, CKEditor 5 introduces a lock mechanism enabling/disabling the read-only mode.
// As it is a breaking change between major releases of the integration, the component requires using
// CKEditor 5 in version 34 or higher.
if ( CKEDITOR_VERSION ) {
const [ major ] = CKEDITOR_VERSION.split( '.' ).map( Number );

if ( major < 34 ) {
console.warn( 'The <CKEditor> component requires using CKEditor 5 in version 34 or higher.' );
}
} else {
console.warn( 'Cannot find the "CKEDITOR_VERSION" in the "window" scope.' );
}
}

/**
Expand Down Expand Up @@ -61,7 +80,7 @@ export default class CKEditor extends React.Component {
}

if ( 'disabled' in nextProps ) {
this.editor.isReadOnly = nextProps.disabled;
this.editor.enableReadOnlyMode( REACT_INTEGRATION_READ_ONLY_LOCK_ID, nextProps.disabled );
}

return false;
Expand Down Expand Up @@ -134,7 +153,7 @@ export default class CKEditor extends React.Component {
return this.props.editor.create( element, config )
.then( editor => {
if ( 'disabled' in this.props ) {
editor.isReadOnly = this.props.disabled;
editor.enableReadOnlyMode( REACT_INTEGRATION_READ_ONLY_LOCK_ID, this.props.disabled );
}

const modelDocument = editor.model.document;
Expand Down Expand Up @@ -264,7 +283,7 @@ class EditorWatchdogAdapter {
/**
* Adds an editor configuration to the context watchdog registry. Creates an instance of it.
*
* @param {HTMLElement | string} sourceElementOrData A source element or data for the new editor.
* @param {HTMLElement|string} sourceElementOrData A source element or data for the new editor.
* @param {Object} config CKEditor 5 editor config.
* @returns {Promise}
*/
Expand Down
50 changes: 49 additions & 1 deletion tests/_utils-tests/editor.js
Expand Up @@ -13,12 +13,60 @@ describe( 'Editor', () => {
expect( editor.model ).is.not.undefined;
expect( editor.editing ).is.not.undefined;
} );
} );

describe( 'enableReadOnlyMode()', () => {
it( 'should enable the read-only mode for given identifier when passing "true" as the second argument', async () => {
const editor = await Editor.create();

expect( editor.isReadOnly ).is.false;

editor.enableReadOnlyMode( 'foo', true );

expect( editor.isReadOnly ).is.true;
} );

it( 'should disable the read-only mode for given identifier when passing "false" as the second argument', async () => {
const editor = await Editor.create();

expect( editor.isReadOnly ).is.false;

editor.enableReadOnlyMode( 'foo', false );

expect( editor.isReadOnly ).is.false;
} );
} );

describe( 'disableReadOnlyMode()', () => {
it( 'should enable the read-only mode for given lock identifier', async () => {
const editor = await Editor.create();

expect( editor.isReadOnly ).is.false;

editor.enableReadOnlyMode( 'foo', true );

expect( editor.isReadOnly ).is.true;

editor.disableReadOnlyMode( 'foo' );

it( 'read-only mode is disabled by default', () => {
expect( editor.isReadOnly ).is.false;
} );
} );

describe( '#isReadOnly', () => {
it( 'should be disabled by default when creating a new instance of the editor', () => {
const editor = new Editor();

expect( editor.isReadOnly ).is.false;
} );

it( 'should throw an error when using the setter for switching to read-only mode', async () => {
const editor = await Editor.create();

expect( () => {
editor.isReadOnly = true;
} ).to.throw( Error, 'Cannot use this setter anymore' );
} );
} );

describe( 'destroy()', () => {
Expand Down
26 changes: 25 additions & 1 deletion tests/_utils/editor.js
Expand Up @@ -10,9 +10,12 @@
*/
export default class Editor {
constructor() {
this.initializeProperties();
}

initializeProperties() {
this.model = Editor._model;
this.editing = Editor._editing;
this.isReadOnly = false;
this.data = {
get() {
return '';
Expand All @@ -21,6 +24,27 @@ export default class Editor {

}
};
this._readOnlyLocks = new Set();
}

get isReadOnly() {
return this._readOnlyLocks.size > 0;
}

set isReadOnly( value ) {
throw new Error( 'Cannot use this setter anymore' );
}

enableReadOnlyMode( lockId, value ) {
if ( value ) {
this._readOnlyLocks.add( lockId );
} else {
this.disableReadOnlyMode( lockId );
}
}

disableReadOnlyMode( lockId ) {
this._readOnlyLocks.delete( lockId );
}

destroy() {
Expand Down

0 comments on commit 00f695e

Please sign in to comment.