Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
51 changes: 35 additions & 16 deletions .eslintrc.js → .eslintrc.cjs
Original file line number Diff line number Diff line change
@@ -1,37 +1,56 @@
/* eslint-env node */

'use strict';

module.exports = {
extends: 'ckeditor5',
extends: [
"ckeditor5",
"plugin:@typescript-eslint/strict",
"plugin:@typescript-eslint/stylistic-type-checked",
],
root: true,
plugins: ["@typescript-eslint"],
parser: "@typescript-eslint/parser",
parserOptions: {
project: true,
__tsconfigRootDir: __dirname,
ecmaVersion: "latest",
sourceType: "module",
},
globals: {
'MathJax': true,
'katex': true,
'console': true
MathJax: true,
katex: true,
console: true,
},
ignorePatterns: [
// Ignore the entire `build/` (the DLL build).
'build/**'
"build/**",
],
rules: {
// This rule disallows importing core DLL packages directly. Imports should be done using the `ckeditor5` package.
// Also, importing non-DLL packages is not allowed. If the package requires other features to work, they should be
// specified as soft-requirements.
// Read more: https://ckeditor.com/docs/ckeditor5/latest/builds/guides/migration/migration-to-26.html#soft-requirements.
'ckeditor5-rules/ckeditor-imports': 'error',
"ckeditor5-rules/ckeditor-imports": "error",

// This rule could not be found ???
'ckeditor5-rules/use-require-for-debug-mode-imports': 'off'
"ckeditor5-rules/use-require-for-debug-mode-imports": "off",

"no-void": ["error", { allowAsStatement: true }],
},
overrides: [
{
files: [ 'tests/**/*.js', 'sample/**/*.js' ],
files: ["tests/**/*.js", "sample/**/*.js"],
rules: {
// To write complex tests, you may need to import files that are not exported in DLL files by default.
// Hence, imports CKEditor 5 packages in test files are not checked.
'ckeditor5-rules/ckeditor-imports': 'off'
}
}
]
"ckeditor5-rules/ckeditor-imports": "off",
},
},
{
env: {
node: true,
},
files: [".eslintrc.{js,cjs}"],
parserOptions: {
sourceType: "script",
},
},
],
};
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,4 @@ tmp/
sample/ckeditor.dist.js
package-lock.json
yarn-error.log
src/**/*.js
10 changes: 9 additions & 1 deletion .prettierrc
Original file line number Diff line number Diff line change
@@ -1,3 +1,11 @@
{
"embeddedLanguageFormatting": "off"
"embeddedLanguageFormatting": "off",
"overrides": [
{
"files": "*.json",
"options": {
"tabWidth": 2
}
}
]
}
17 changes: 10 additions & 7 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
"ckeditor5-feature",
"ckeditor5-plugin",
"ckeditor5-math",
"katex"
"katex"
],
"main": "src/index.js",
"dependencies": {
Expand All @@ -35,13 +35,16 @@
"@ckeditor/ckeditor5-table": "41.2.0",
"@ckeditor/ckeditor5-theme-lark": "41.2.0",
"@ckeditor/ckeditor5-upload": "41.2.0",
"eslint": "^7.32.0",
"@typescript-eslint/eslint-plugin": "^7.1.0",
"@typescript-eslint/parser": "^7.1.0",
"eslint": "^8.57.0",
"eslint-config-ckeditor5": "^5.3.0",
"http-server": "^14.1.0",
"husky": "^4.2.5",
"lint-staged": "^10.2.6",
"stylelint": "^13.13.1",
"stylelint-config-ckeditor5": ">=5.3.0"
"stylelint-config-ckeditor5": ">=5.3.0",
"typescript": "5.1.6"
},
"engines": {
"node": ">=18.0.0",
Expand All @@ -65,16 +68,16 @@
"scripts": {
"dll:build": "ckeditor5-package-tools dll:build",
"dll:serve": "http-server ./ -o sample/dll.html",
"lint": "eslint --quiet src/**/*.js",
"lint:fix": "eslint --quiet src/**/*.js --fix",
"lint": "eslint --quiet --ext .ts src/",
"lint:fix": "eslint --quiet --fix --ext .ts src/",
"stylelint": "stylelint --quiet --allow-empty-input 'theme/**/*.css'",
"test": "ckeditor5-package-tools test",
"prepare": "yarn run dll:build",
"start": "ckeditor5-package-tools start"
},
"lint-staged": {
"**/*.js": [
"eslint --quiet"
"**/*.ts": [
"eslint --quiet --fix"
],
"**/*.css": [
"stylelint --quiet --allow-empty-input"
Expand Down
22 changes: 22 additions & 0 deletions src/augmentation.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import type { KatexOptions } from './katex';

declare module '@ckeditor/ckeditor5-core' {
interface EditorConfig {
math?: {
engine?:
| 'mathjax'
| 'katex'
| ( ( equation: string, element: HTMLElement, display: boolean ) => void )
| undefined;
lazyLoad?: undefined | ( () => Promise<void> );
outputType?: 'script' | 'span' | undefined;
className?: string | undefined;
forceOutputType?: boolean | undefined;
enablePreview?: boolean | undefined;
previewClassName?: Array<string> | undefined;
popupClassName?: Array<string> | undefined;
katexRenderOptions?: Partial<KatexOptions> | undefined;
};
}
}

26 changes: 18 additions & 8 deletions src/autoformatmath.js → src/autoformatmath.ts
Original file line number Diff line number Diff line change
@@ -1,29 +1,32 @@
import { Plugin } from 'ckeditor5/src/core';
import { global, logWarning } from 'ckeditor5/src/utils';
// eslint-disable-next-line ckeditor5-rules/allow-imports-only-from-main-package-entry-point
import blockAutoformatEditing from '@ckeditor/ckeditor5-autoformat/src/blockautoformatediting';
import Math from './math';
import MathCommand from './mathcommand';
import MathUI from './mathui';

export default class AutoformatMath extends Plugin {
static get requires() {
return [ Math, 'Autoformat' ];
public static get requires() {
return [ Math, 'Autoformat' ] as const;
}

/**
* @inheritDoc
*/
init() {
public init(): void {
const editor = this.editor;

if ( !editor.plugins.has( 'Math' ) ) {
logWarning( 'autoformat-math-feature-missing', editor );
}
}

afterInit() {
public afterInit(): void {
const editor = this.editor;
const command = editor.commands.get( 'math' );

if ( command ) {
if ( command instanceof MathCommand ) {
const callback = () => {
if ( !command.isEnabled ) {
return false;
Expand All @@ -33,17 +36,24 @@ export default class AutoformatMath extends Plugin {

// Wait until selection is removed.
global.window.setTimeout(
() => editor.plugins.get( 'MathUI' )._showUI(),
() => {
const mathUIInstance = editor.plugins.get( 'MathUI' );
if ( mathUIInstance instanceof MathUI ) {
mathUIInstance._showUI();
}
},
50
);
};

// @ts-expect-error: blockAutoformatEditing expects an Autoformat instance even though it works with any Plugin instance
blockAutoformatEditing( editor, this, /^\$\$$/, callback );
// @ts-expect-error: blockAutoformatEditing expects an Autoformat instance even though it works with any Plugin instance
blockAutoformatEditing( editor, this, /^\\\[$/, callback );
}
}

static get pluginName() {
return 'AutoformatMath';
public static get pluginName() {
return 'AutoformatMath' as const;
}
}
55 changes: 36 additions & 19 deletions src/automath.js → src/automath.ts
Original file line number Diff line number Diff line change
@@ -1,33 +1,39 @@
import { Clipboard } from 'ckeditor5/src/clipboard';
import { Plugin } from 'ckeditor5/src/core';
import { Plugin, type Editor } from 'ckeditor5/src/core';
import { LivePosition, LiveRange } from 'ckeditor5/src/engine';
import { Undo } from 'ckeditor5/src/undo';
import { global } from 'ckeditor5/src/utils';
import { extractDelimiters, hasDelimiters, delimitersCounts } from './utils';

export default class AutoMath extends Plugin {
static get requires() {
return [ Clipboard, Undo ];
public static get requires() {
return [ Clipboard, Undo ] as const;
}

static get pluginName() {
return 'AutoMath';
public static get pluginName() {
return 'AutoMath' as const;
}

constructor( editor ) {
private _timeoutId: null | number;
private _positionToInsert: null | LivePosition;

constructor( editor: Editor ) {
super( editor );

this._timeoutId = null;

this._positionToInsert = null;
}

init() {
public init(): void {
const editor = this.editor;
const modelDocument = editor.model.document;

this.listenTo( editor.plugins.get( Clipboard ), 'inputTransformation', () => {
const firstRange = modelDocument.selection.getFirstRange();
if ( !firstRange ) {
return;
}

const leftLivePosition = LivePosition.fromPosition( firstRange.start );
leftLivePosition.stickiness = 'toPrevious';
Expand All @@ -36,28 +42,38 @@ export default class AutoMath extends Plugin {
rightLivePosition.stickiness = 'toNext';

modelDocument.once( 'change:data', () => {
this._mathBetweenPositions( leftLivePosition, rightLivePosition );
this._mathBetweenPositions(
leftLivePosition,
rightLivePosition
);

leftLivePosition.detach();
rightLivePosition.detach();
}, { priority: 'high' } );
} );
},
{ priority: 'high' }
);
}
);

editor.commands.get( 'undo' ).on( 'execute', () => {
editor.commands.get( 'undo' )?.on( 'execute', () => {
if ( this._timeoutId ) {
global.window.clearTimeout( this._timeoutId );
this._positionToInsert.detach();
this._positionToInsert?.detach();

this._timeoutId = null;
this._positionToInsert = null;
}
}, { priority: 'high' } );
}

_mathBetweenPositions( leftPosition, rightPosition ) {
private _mathBetweenPositions(
leftPosition: LivePosition,
rightPosition: LivePosition
) {
const editor = this.editor;

const mathConfig = this.editor.config.get( 'math' );
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
const mathConfig = this.editor.config.get( 'math' )!;

const equationRange = new LiveRange( leftPosition, rightPosition );
const walker = equationRange.getWalker( { ignoreElementEnd: true } );
Expand All @@ -81,7 +97,7 @@ export default class AutoMath extends Plugin {
const mathCommand = editor.commands.get( 'math' );

// Do not anything if math element cannot be inserted at the current position
if ( !mathCommand.isEnabled ) {
if ( !mathCommand?.isEnabled ) {
return;
}

Expand All @@ -94,25 +110,26 @@ export default class AutoMath extends Plugin {

writer.remove( equationRange );

let insertPosition;
let insertPosition: LivePosition | null;

// Check if position where the math element should be inserted is still valid.
if ( this._positionToInsert.root.rootName !== '$graveyard' ) {
if ( this._positionToInsert?.root.rootName !== '$graveyard' ) {
insertPosition = this._positionToInsert;
}

editor.model.change( innerWriter => {
const params = Object.assign( extractDelimiters( text ), {
type: mathConfig.outputType
} );
const mathElement = innerWriter.createElement( params.display ? 'mathtex-display' : 'mathtex-inline', params );
const mathElement = innerWriter.createElement( params.display ? 'mathtex-display' : 'mathtex-inline', params
);

editor.model.insertContent( mathElement, insertPosition );

innerWriter.setSelection( mathElement, 'on' );
} );

this._positionToInsert.detach();
this._positionToInsert?.detach();
this._positionToInsert = null;
} );
}, 100 );
Expand Down
File renamed without changes.
Loading