Skip to content

Commit

Permalink
Merge pull request #13409 from ckeditor/ck/13029-move-restricted-edit…
Browse files Browse the repository at this point in the history
…ing-plugin-to-typescript

Other (restricted-editing): Rewrite 'ckeditor5-restricted-editing' to TypeScript. Closes #13029.
  • Loading branch information
arkflpc authored Feb 10, 2023
2 parents e14232f + 978ee2b commit 5210780
Show file tree
Hide file tree
Showing 36 changed files with 1,524 additions and 21 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ packages/ckeditor5-minimap/src/**/*.js
packages/ckeditor5-page-break/src/**/*.js
packages/ckeditor5-paragraph/src/**/*.js
packages/ckeditor5-paste-from-office/src/**/*.js
packages/ckeditor5-restricted-editing/src/**/*.js
packages/ckeditor5-select-all/src/**/*.js
packages/ckeditor5-typing/src/**/*.js
packages/ckeditor5-ui/src/**/*.js
Expand Down
4 changes: 3 additions & 1 deletion packages/ckeditor5-clipboard/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,10 @@
export { default as Clipboard } from './clipboard';
export {
default as ClipboardPipeline,
type ClipboardContentInsertionEvent,
type ClipboardInputTransformationEvent,
type ClipboardInputTransformationData
type ClipboardInputTransformationData,
type ClipboardOutputEvent
} from './clipboardpipeline';
export { default as DragDrop } from './dragdrop';
export { default as PastePlainText } from './pasteplaintext';
Expand Down
7 changes: 6 additions & 1 deletion packages/ckeditor5-core/src/editingkeystrokehandler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ export default class EditingKeystrokeHandler extends KeystrokeHandler {
*/
public override set(
keystroke: string | Array<string | number>,
callback: string | ( ( ev: KeyboardEvent, cancel: () => void ) => void ),
callback: EditingKeystrokeCallback,
options: { readonly priority?: PriorityString } = {}
): void {
if ( typeof callback == 'string' ) {
Expand All @@ -78,3 +78,8 @@ export default class EditingKeystrokeHandler extends KeystrokeHandler {
super.set( keystroke, callback, options );
}
}

/**
* Command name or a callback to be executed when a given keystroke is pressed.
*/
export type EditingKeystrokeCallback = string | ( ( ev: KeyboardEvent, cancel: () => void ) => void );
1 change: 1 addition & 0 deletions packages/ckeditor5-core/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ export type { PluginsMap, default as PluginCollection } from './plugincollection

export { default as Context, type ContextConfig } from './context';
export { default as ContextPlugin, type ContextPluginDependencies } from './contextplugin';
export { type EditingKeystrokeCallback } from './editingkeystrokehandler';

export { default as Editor, type EditorReadyEvent, type EditorDestroyEvent } from './editor/editor';
export type {
Expand Down
8 changes: 6 additions & 2 deletions packages/ckeditor5-engine/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -70,14 +70,18 @@ export { default as Position } from './model/position';
export { default as DocumentFragment } from './model/documentfragment';
export { default as History } from './model/history';
export { default as Text } from './model/text';
export type { default as Document } from './model/document';
export type { default as Document, ModelPostFixer } from './model/document';
export type { Marker } from './model/markercollection';
export type { default as Batch } from './model/batch';
export type { DiffItem, DiffItemAttribute, DiffItemInsert, DiffItemRemove } from './model/differ';
export type { default as Item } from './model/item';
export type { default as Node } from './model/node';
export type { default as RootElement } from './model/rootelement';
export type { default as Schema } from './model/schema';
export type {
default as Schema,
SchemaAttributeCheckCallback,
SchemaChildCheckCallback
} from './model/schema';
export type { default as Selection, Selectable } from './model/selection';
export type { default as TypeCheckable } from './model/typecheckable';
export type { default as Writer } from './model/writer';
Expand Down
9 changes: 7 additions & 2 deletions packages/ckeditor5-engine/src/model/document.ts
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ export default class Document extends EmitterMixin() {
/**
* Post-fixer callbacks registered to the model document.
*/
private readonly _postFixers: Set<( writer: Writer ) => boolean>;
private readonly _postFixers: Set<ModelPostFixer>;

/**
* A boolean indicates whether the selection has changed until
Expand Down Expand Up @@ -266,7 +266,7 @@ export default class Document extends EmitterMixin() {
* } );
* ```
*/
public registerPostFixer( postFixer: ( writer: Writer ) => boolean ): void {
public registerPostFixer( postFixer: ModelPostFixer ): void {
this._postFixers.add( postFixer );
}

Expand Down Expand Up @@ -445,6 +445,11 @@ export type DocumentChangeEvent = {
args: [ batch: Batch ];
};

/**
* Callback passed as an argument to the {@link module:engine/model/document~Document#registerPostFixer} method.
*/
export type ModelPostFixer = ( writer: Writer ) => boolean;

/**
* Checks whether given range boundary position is valid for document selection, meaning that is not between
* unicode surrogate pairs or base character and combining marks.
Expand Down
8 changes: 6 additions & 2 deletions packages/ckeditor5-engine/src/model/schema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -516,7 +516,7 @@ export default class Schema extends ObservableMixin() {
* The callback may return `true/false` to override `checkChild()`'s return value. If it does not return
* a boolean value, the default algorithm (or other callbacks) will define `checkChild()`'s return value.
*/
public addChildCheck( callback: ( ctx: SchemaContext, def: SchemaCompiledItemDefinition ) => unknown ): void {
public addChildCheck( callback: SchemaChildCheckCallback ): void {
this.on<SchemaCheckChildEvent>( 'checkChild', ( evt, [ ctx, childDef ] ) => {
// checkChild() was called with a non-registered child.
// In 99% cases such check should return false, so not to overcomplicate all callbacks
Expand Down Expand Up @@ -577,7 +577,7 @@ export default class Schema extends ObservableMixin() {
* The callback may return `true/false` to override `checkAttribute()`'s return value. If it does not return
* a boolean value, the default algorithm (or other callbacks) will define `checkAttribute()`'s return value.
*/
public addAttributeCheck( callback: ( context: SchemaContext, attributeName: string ) => unknown ): void {
public addAttributeCheck( callback: SchemaAttributeCheckCallback ): void {
this.on<SchemaCheckAttributeEvent>( 'checkAttribute', ( evt, [ ctx, attributeName ] ) => {
const retValue = callback( ctx, attributeName );

Expand Down Expand Up @@ -1767,6 +1767,10 @@ export interface AttributeProperties {
[ name: string ]: unknown;
}

export type SchemaAttributeCheckCallback = ( context: SchemaContext, attributeName: string ) => unknown;

export type SchemaChildCheckCallback = ( ctx: SchemaContext, def: SchemaCompiledItemDefinition ) => unknown;

function compileBaseItemRule( sourceItemRules: Array<SchemaItemDefinition>, itemName: string ): SchemaCompiledItemDefinitionInternal {
const itemRule = {
name: itemName,
Expand Down
10 changes: 7 additions & 3 deletions packages/ckeditor5-restricted-editing/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
"ckeditor5-lib",
"ckeditor5-dll"
],
"main": "src/index.js",
"main": "src/index.ts",
"dependencies": {
"ckeditor5": "^36.0.1"
},
Expand All @@ -29,6 +29,7 @@
"@ckeditor/ckeditor5-ui": "^36.0.1",
"@ckeditor/ckeditor5-undo": "^36.0.1",
"@ckeditor/ckeditor5-utils": "^36.0.1",
"typescript": "^4.8.4",
"webpack": "^5.58.1",
"webpack-cli": "^4.9.0"
},
Expand All @@ -47,13 +48,16 @@
},
"files": [
"lang",
"src",
"src/**/*.js",
"src/**/*.d.ts",
"theme",
"build",
"ckeditor5-metadata.json",
"CHANGELOG.md"
],
"scripts": {
"dll:build": "webpack"
"dll:build": "webpack",
"build": "tsc -p ./tsconfig.release.json",
"postversion": "npm run build"
}
}
15 changes: 15 additions & 0 deletions packages/ckeditor5-restricted-editing/src/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
/**
* @license Copyright (c) 2003-2023, CKSource Holding sp. z o.o. All rights reserved.
* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
*/

/**
* @module restricted-editing
*/

export { default as RestrictedEditingMode } from './restrictededitingmode';
export { default as RestrictedEditingModeEditing } from './restrictededitingmodeediting';
export { default as RestrictedEditingModeUI } from './restrictededitingmodeui';
export { default as StandardEditingMode } from './standardeditingmode';
export { default as StandardEditingModeEditing } from './standardeditingmodeediting';
export { default as StandardEditingModeUI } from './standardeditingmodeui';
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
/**
* @license Copyright (c) 2003-2023, CKSource Holding sp. z o.o. All rights reserved.
* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
*/

/**
* @module restricted-editing/restrictededitingconfig
*/

/**
* The configuration of the restricted editing mode feature.
* The option is used by the {@link module:restricted-editing/restrictededitingmode~RestrictedEditingMode} feature.
*
* ```ts
* ClassicEditor
* .create( {
* restrictedEditing: {
* allowedCommands: [ 'bold', 'link', 'unlink' ],
* allowedAttributes: [ 'bold', 'linkHref' ]
* }
* } )
* .then( ... )
* .catch( ... );
* ```
*
* See {@link module:core/editor/editorconfig~EditorConfig all editor options}.
*/
export interface RestrictedEditingConfig {

/**
* The command names allowed in non-restricted areas of the content.
*
* Defines which feature commands should be enabled in the restricted editing mode. The commands used for typing and deleting text
* (`'input'`, `'delete'` and `'deleteForward'`) are allowed by the feature inside non-restricted regions and do not need to be defined.
*
* **Note**: The restricted editing mode always allows to use the restricted mode navigation commands as well as `'undo'` and `'redo'`
* commands.
*
* The default value is:
*
* ```ts
* const restrictedEditingConfig = {
* allowedCommands: [ 'bold', 'italic', 'link', 'unlink' ]
* };
* ```
*
* To make a command always enabled (also outside non-restricted areas) use
* {@link module:restricted-editing/restrictededitingconfig~RestrictedEditingModeEditing#enableCommand} method.
*/
allowedCommands: Array<string>;

/**
* The text attribute names allowed when pasting content ot non-restricted areas.
*
* The default value is:
*
* ```ts
* const restrictedEditingConfig = {
* allowedAttributes: [ 'bold', 'italic', 'linkHref' ]
* };
* ```
*/
allowedAttributes: Array<string>;
}

declare module '@ckeditor/ckeditor5-core' {

/**
* The configuration of the restricted editing mode feature. Introduced by the
* {@link module:restricted-editing/restrictededitingmode~RestrictedEditingMode} feature.
*
* Read more in {@link module:restricted-editing/restrictededitingmode~RestrictedEditingModeConfig}.
*/
interface EditorConfig {
restrictedEditing?: RestrictedEditingConfig;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
/**
* @license Copyright (c) 2003-2023, CKSource Holding sp. z o.o. All rights reserved.
* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
*/

/**
* @module restricted-editing/restrictededitingexceptioncommand
*/

import { Command } from 'ckeditor5/src/core';
import type { TreeWalkerValue } from 'ckeditor5/src/engine';

/**
* The command that toggles exceptions from the restricted editing on text.
*/
export default class RestrictedEditingExceptionCommand extends Command {
/**
* A flag indicating whether the command is active
*
* @readonly
*/
declare public value: boolean;

/**
* @inheritDoc
*/
public override refresh(): void {
const model = this.editor.model;
const doc = model.document;

this.value = !!doc.selection.getAttribute( 'restrictedEditingException' );

this.isEnabled = model.schema.checkAttributeInSelection( doc.selection, 'restrictedEditingException' );
}

/**
* @inheritDoc
*/
public override execute( options: RestrictedEditingExceptionCommandParams = {} ): void {
const model = this.editor.model;
const document = model.document;
const selection = document.selection;
const valueToSet = ( options.forceValue === undefined ) ? !this.value : options.forceValue;

model.change( writer => {
const ranges = model.schema.getValidRanges( selection.getRanges(), 'restrictedEditingException' );

if ( selection.isCollapsed ) {
if ( valueToSet ) {
writer.setSelectionAttribute( 'restrictedEditingException', valueToSet );
} else {
const isSameException = ( value: TreeWalkerValue ) => {
return value.item.getAttribute( 'restrictedEditingException' ) === this.value;
};

const focus = selection.focus!;
const exceptionStart = focus.getLastMatchingPosition( isSameException, { direction: 'backward' } );
const exceptionEnd = focus.getLastMatchingPosition( isSameException );

writer.removeSelectionAttribute( 'restrictedEditingException' );

if ( !( focus.isEqual( exceptionStart ) || focus.isEqual( exceptionEnd ) ) ) {
writer.removeAttribute( 'restrictedEditingException', writer.createRange( exceptionStart, exceptionEnd ) );
}
}
} else {
for ( const range of ranges ) {
if ( valueToSet ) {
writer.setAttribute( 'restrictedEditingException', valueToSet, range );
} else {
writer.removeAttribute( 'restrictedEditingException', range );
}
}
}
} );
}
}

export interface RestrictedEditingExceptionCommandParams {
forceValue?: unknown;
}

declare module '@ckeditor/ckeditor5-core' {
interface CommandsMap {
restrictedEditingException: RestrictedEditingExceptionCommand;
}
}
45 changes: 45 additions & 0 deletions packages/ckeditor5-restricted-editing/src/restrictededitingmode.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
/**
* @license Copyright (c) 2003-2023, CKSource Holding sp. z o.o. All rights reserved.
* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
*/

/**
* @module restricted-editing/restrictededitingmode
*/

import { Plugin, type PluginDependencies } from 'ckeditor5/src/core';

import RestrictedEditingModeEditing from './restrictededitingmodeediting';
import RestrictedEditingModeUI from './restrictededitingmodeui';

import '../theme/restrictedediting.css';

/**
* The restricted editing mode plugin.
*
* This is a "glue" plugin which loads the following plugins:
*
* * The {@link module:restricted-editing/restrictededitingmodeediting~RestrictedEditingModeEditing restricted mode editing feature}.
* * The {@link module:restricted-editing/restrictededitingmodeui~RestrictedEditingModeUI restricted mode UI feature}.
*/
export default class RestrictedEditingMode extends Plugin {
/**
* @inheritDoc
*/
public static get pluginName(): 'RestrictedEditingMode' {
return 'RestrictedEditingMode';
}

/**
* @inheritDoc
*/
public static get requires(): PluginDependencies {
return [ RestrictedEditingModeEditing, RestrictedEditingModeUI ];
}
}

declare module '@ckeditor/ckeditor5-core' {
interface PluginsMap {
[ RestrictedEditingMode.pluginName ]: RestrictedEditingMode;
}
}
Loading

0 comments on commit 5210780

Please sign in to comment.