From 7d0cd0187f30808676363b8bdce59dbcfcb23aac Mon Sep 17 00:00:00 2001 From: Sauli Anto Date: Sat, 29 Aug 2020 17:33:41 +0300 Subject: [PATCH] Fix writer and seperate schema --- .eslintrc.js | 3 +- .gitignore | 1 + README.md | 11 +------ package.json | 47 ++++++++++++++-------------- src/automath.js | 4 +-- src/math.js | 2 +- src/mathcommand.js | 13 +++++--- src/mathediting.js | 76 ++++++++++++++++++++++++++++------------------ src/utils.js | 4 +-- theme/mathform.css | 28 ++++++++--------- 10 files changed, 101 insertions(+), 88 deletions(-) diff --git a/.eslintrc.js b/.eslintrc.js index 56069ab43..615d22990 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -6,6 +6,7 @@ module.exports = { extends: 'ckeditor5', globals: { 'MathJax': true, - 'katex': true + 'katex': true, + 'console': true } }; diff --git a/.gitignore b/.gitignore index beea512cb..0169617fe 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ node_modules/ build/ package-lock.json +yarn.lock diff --git a/README.md b/README.md index 30dfdcfa1..ee56e905d 100644 --- a/README.md +++ b/README.md @@ -28,7 +28,6 @@ This is TeX-based mathematical plugin for CKEditor 5. You can use it to insert, - Have multiple input and output format - Paste support - from plain text - - from Microsoft Word # Demos [Classic editor with MathJax](https://jsfiddle.net/isaul32/qktj9h7x/) @@ -42,11 +41,7 @@ This is TeX-based mathematical plugin for CKEditor 5. You can use it to insert, ## Requirements -- With CKEditor 5 v21.0.0, use ckeditor5-math@21.0.0 version -- With CKEditor 5 v20.0.0, use ckeditor5-math@20.0.0 version -- With CKEditor 5 v19.0.0, use ckeditor5-math@19.0.0 version -- With CKEditor 5 v18.0.0, use ckeditor5-math@18.0.0 version -- With CKEditor 5 v17.0.0, use ckeditor5-math@17.0.1 version +- Use same version as CKEditor 5 If you get duplicated modules error, you have mismatching versions in your editor build package.json. @@ -176,7 +171,3 @@ Replace ckeditor5-core with git version Run test suite `npm run test` - -## Todo -- MathML input and output when using MathJax version 3 -- Support multiple equations when pasting as plain text diff --git a/package.json b/package.json index d095fe087..f8e81075e 100644 --- a/package.json +++ b/package.json @@ -1,37 +1,38 @@ { "name": "ckeditor5-math", - "version": "21.0.0", + "version": "22.0.0", "description": "Math feature for CKEditor 5.", "keywords": [ "ckeditor", "ckeditor5", "ckeditor 5", "ckeditor5-feature", - "ckeditor5-plugin" + "ckeditor5-plugin", + "ckeditor5-math" ], "dependencies": { - "@ckeditor/ckeditor5-clipboard": "^21.0.0", - "@ckeditor/ckeditor5-core": "^21.0.0", - "@ckeditor/ckeditor5-engine": "^21.0.0", - "@ckeditor/ckeditor5-ui": "^21.0.0", - "@ckeditor/ckeditor5-undo": "^21.0.0", - "@ckeditor/ckeditor5-utils": "^21.0.0", - "@ckeditor/ckeditor5-widget": "^21.0.0" + "@ckeditor/ckeditor5-clipboard": "^22.0.0", + "@ckeditor/ckeditor5-core": "^22.0.0", + "@ckeditor/ckeditor5-engine": "^22.0.0", + "@ckeditor/ckeditor5-ui": "^22.0.0", + "@ckeditor/ckeditor5-undo": "^22.0.0", + "@ckeditor/ckeditor5-utils": "^22.0.0", + "@ckeditor/ckeditor5-widget": "^22.0.0" }, "devDependencies": { - "@ckeditor/ckeditor5-dev-tests": "^21.0.0", - "@ckeditor/ckeditor5-editor-inline": "^21.0.0", - "@ckeditor/ckeditor5-essentials": "^21.0.0", - "@ckeditor/ckeditor5-paragraph": "^21.0.0", - "eslint": "^5.5.0", - "eslint-config-ckeditor5": "^2.0.0", - "husky": "^1.3.1", - "lint-staged": "^7.0.0", - "stylelint": "^11.1.1", - "stylelint-config-ckeditor5": "^1.0.0" + "@ckeditor/ckeditor5-dev-tests": "^22.0.0", + "@ckeditor/ckeditor5-editor-inline": "^22.0.0", + "@ckeditor/ckeditor5-essentials": "^22.0.0", + "@ckeditor/ckeditor5-paragraph": "^22.0.0", + "eslint": "^7.1.0", + "eslint-config-ckeditor5": "^3.0.0", + "husky": "^4.2.5", + "lint-staged": "^10.2.6", + "stylelint": "^13.5.0", + "stylelint-config-ckeditor5": "^2.0.0" }, "engines": { - "node": ">=8.0.0", + "node": ">=12.0.0", "npm": ">=5.7.1" }, "author": "Sauli Anto", @@ -61,8 +62,10 @@ ] }, "eslintIgnore": [ - "src/lib/**", - "packages/**" + "node_modules/**", + "packages/*/node_modules/**", + "packages/*/build/**", + "packages/*/src/lib/**" ], "husky": { "hooks": { diff --git a/src/automath.js b/src/automath.js index e2cf19286..11cadeeef 100644 --- a/src/automath.js +++ b/src/automath.js @@ -68,7 +68,7 @@ export default class AutoMath extends Plugin { // Get equation text for ( const node of walker ) { - if ( node.item.is( 'textProxy' ) ) { + if ( node.item.is( '$textProxy' ) ) { text += node.item.data; } } @@ -107,7 +107,7 @@ export default class AutoMath extends Plugin { const params = Object.assign( extractDelimiters( text ), { type: mathConfig.outputType } ); - const mathElement = writer.createElement( 'mathtex', params ); + const mathElement = writer.createElement( params.display ? 'mathtex-display' : 'mathtex-inline', params ); editor.model.insertContent( mathElement, insertPosition ); diff --git a/src/math.js b/src/math.js index 73f753082..62a4380bc 100644 --- a/src/math.js +++ b/src/math.js @@ -7,7 +7,7 @@ import AutoMath from './automath'; export default class Math extends Plugin { static get requires() { - return [ MathEditing, MathUI, Widget, AutoMath ]; + return [ MathEditing, MathUI, AutoMath, Widget ]; } static get pluginName() { diff --git a/src/mathcommand.js b/src/mathcommand.js index 9e0fd73ca..11c540164 100644 --- a/src/mathcommand.js +++ b/src/mathcommand.js @@ -1,4 +1,5 @@ import Command from '@ckeditor/ckeditor5-core/src/command'; + import { getSelectedMathModelWidget } from './utils'; export default class MathCommand extends Command { @@ -9,17 +10,18 @@ export default class MathCommand extends Command { model.change( writer => { let mathtex; - if ( selectedElement && selectedElement.is( 'mathtex' ) ) { + if ( selectedElement && ( selectedElement.is( 'element', 'mathtex-inline' ) || + selectedElement.is( 'element', 'mathtex-display' ) ) ) { // Update selected element const typeAttr = selectedElement.getAttribute( 'type' ); // Use already set type if found and is not forced const type = forceOutputType ? outputType : typeAttr || outputType; - mathtex = writer.createElement( 'mathtex', { equation, type, display } ); + mathtex = writer.createElement( display ? 'mathtex-display' : 'mathtex-inline', { equation, type, display } ); } else { // Create new model element - mathtex = writer.createElement( 'mathtex', { equation, type: outputType, display } ); + mathtex = writer.createElement( display ? 'mathtex-display' : 'mathtex-inline', { equation, type: outputType, display } ); } model.insertContent( mathtex ); writer.setSelection( mathtex, 'on' ); @@ -29,9 +31,10 @@ export default class MathCommand extends Command { refresh() { const model = this.editor.model; const selection = model.document.selection; + const selectedElement = selection.getSelectedElement(); - const isAllowed = model.schema.checkChild( selection.focus.parent, 'mathtex' ); - this.isEnabled = isAllowed; + this.isEnabled = selectedElement === null || ( selectedElement.is( 'element', 'mathtex-inline' ) || + selectedElement.is( 'element', 'mathtex-display' ) ); const selectedEquation = getSelectedMathModelWidget( selection ); this.value = selectedEquation ? selectedEquation.getAttribute( 'equation' ) : null; diff --git a/src/mathediting.js b/src/mathediting.js index 32a18d906..13524cc57 100644 --- a/src/mathediting.js +++ b/src/mathediting.js @@ -36,13 +36,19 @@ export default class MathEditing extends Plugin { _defineSchema() { const schema = this.editor.model.schema; - - schema.register( 'mathtex', { + schema.register( 'mathtex-inline', { allowWhere: '$text', isInline: true, isObject: true, allowAttributes: [ 'equation', 'type', 'display' ] } ); + + schema.register( 'mathtex-display', { + allowWhere: '$block', + isInline: false, + isObject: true, + allowAttributes: [ 'equation', 'type', 'display' ] + } ); } _defineConverters() { @@ -59,9 +65,9 @@ export default class MathEditing extends Plugin { type: 'math/tex' } }, - model: ( viewElement, modelWriter ) => { + model: ( viewElement, { writer } ) => { const equation = viewElement.getChild( 0 ).data.trim(); - return modelWriter.createElement( 'mathtex', { + return writer.createElement( 'mathtex-inline', { equation, type: mathConfig.forceOutputType ? mathConfig.outputType : 'script', display: false @@ -76,9 +82,9 @@ export default class MathEditing extends Plugin { type: 'math/tex; mode=display' } }, - model: ( viewElement, modelWriter ) => { + model: ( viewElement, { writer } ) => { const equation = viewElement.getChild( 0 ).data.trim(); - return modelWriter.createElement( 'mathtex', { + return writer.createElement( 'mathtex-display', { equation, type: mathConfig.forceOutputType ? mathConfig.outputType : 'script', display: true @@ -91,46 +97,58 @@ export default class MathEditing extends Plugin { name: 'span', classes: [ 'math-tex' ] }, - model: ( viewElement, modelWriter ) => { + model: ( viewElement, { writer } ) => { const equation = viewElement.getChild( 0 ).data.trim(); const params = Object.assign( extractDelimiters( equation ), { type: mathConfig.forceOutputType ? mathConfig.outputType : 'span' } ); - return modelWriter.createElement( 'mathtex', params ); + return writer.createElement( params.display ? 'mathtex-display' : 'mathtex-inline', params ); } } ); // Model -> View (element) - conversion.for( 'editingDowncast' ).elementToElement( { - model: 'mathtex', - view: ( modelItem, viewWriter ) => { - const widgetElement = createMathtexEditingView( modelItem, viewWriter ); - return toWidget( widgetElement, viewWriter ); - } - } ); + conversion.for( 'editingDowncast' ) + .elementToElement( { + model: 'mathtex-inline', + view: ( modelItem, { writer } ) => { + const widgetElement = createMathtexEditingView( modelItem, writer ); + return toWidget( widgetElement, writer, 'span' ); + } + } ).elementToElement( { + model: 'mathtex-display', + view: ( modelItem, { writer } ) => { + const widgetElement = createMathtexEditingView( modelItem, writer ); + return toWidget( widgetElement, writer, 'div' ); + } + } ); // Model -> Data - conversion.for( 'dataDowncast' ).elementToElement( { - model: 'mathtex', - view: createMathtexView - } ); + conversion.for( 'dataDowncast' ) + .elementToElement( { + model: 'mathtex-inline', + view: createMathtexView + } ) + .elementToElement( { + model: 'mathtex-display', + view: createMathtexView + } ); // Create view for editor - function createMathtexEditingView( modelItem, viewWriter ) { + function createMathtexEditingView( modelItem, writer ) { const equation = modelItem.getAttribute( 'equation' ); const display = modelItem.getAttribute( 'display' ); const styles = 'user-select: none; ' + ( display ? '' : 'display: inline-block;' ); const classes = 'ck-math-tex ' + ( display ? 'ck-math-tex-display' : 'ck-math-tex-inline' ); - const mathtexView = viewWriter.createContainerElement( 'span', { + const mathtexView = writer.createContainerElement( display ? 'div' : 'span', { style: styles, class: classes } ); - const uiElement = viewWriter.createUIElement( 'div', null, function( domDocument ) { + const uiElement = writer.createUIElement( 'div', null, function( domDocument ) { const domElement = this.toDomElement( domDocument ); renderEquation( equation, domElement, mathConfig.engine, display, false ); @@ -138,35 +156,35 @@ export default class MathEditing extends Plugin { return domElement; } ); - viewWriter.insert( viewWriter.createPositionAt( mathtexView, 0 ), uiElement ); + writer.insert( writer.createPositionAt( mathtexView, 0 ), uiElement ); return mathtexView; } // Create view for data - function createMathtexView( modelItem, viewWriter ) { + function createMathtexView( modelItem, { writer } ) { const equation = modelItem.getAttribute( 'equation' ); const type = modelItem.getAttribute( 'type' ); const display = modelItem.getAttribute( 'display' ); if ( type === 'span' ) { - const mathtexView = viewWriter.createContainerElement( 'span', { + const mathtexView = writer.createContainerElement( 'span', { class: 'math-tex' } ); if ( display ) { - viewWriter.insert( viewWriter.createPositionAt( mathtexView, 0 ), viewWriter.createText( '\\[' + equation + '\\]' ) ); + writer.insert( writer.createPositionAt( mathtexView, 0 ), writer.createText( '\\[' + equation + '\\]' ) ); } else { - viewWriter.insert( viewWriter.createPositionAt( mathtexView, 0 ), viewWriter.createText( '\\(' + equation + '\\)' ) ); + writer.insert( writer.createPositionAt( mathtexView, 0 ), writer.createText( '\\(' + equation + '\\)' ) ); } return mathtexView; } else { - const mathtexView = viewWriter.createContainerElement( 'script', { + const mathtexView = writer.createContainerElement( 'script', { type: display ? 'math/tex; mode=display' : 'math/tex' } ); - viewWriter.insert( viewWriter.createPositionAt( mathtexView, 0 ), viewWriter.createText( equation ) ); + writer.insert( writer.createPositionAt( mathtexView, 0 ), writer.createText( equation ) ); return mathtexView; } diff --git a/src/utils.js b/src/utils.js index b96385590..6d29871de 100644 --- a/src/utils.js +++ b/src/utils.js @@ -1,11 +1,9 @@ -/* globals MathJax, katex, console */ - import global from '@ckeditor/ckeditor5-utils/src/dom/global'; export function getSelectedMathModelWidget( selection ) { const selectedElement = selection.getSelectedElement(); - if ( selectedElement && selectedElement.is( 'mathtex' ) ) { + if ( selectedElement && ( selectedElement.is( 'element', 'mathtex-inline' ) || selectedElement.is( 'element', 'mathtex-display' ) ) ) { return selectedElement; } diff --git a/theme/mathform.css b/theme/mathform.css index 38da47323..fd94e0e96 100644 --- a/theme/mathform.css +++ b/theme/mathform.css @@ -1,24 +1,22 @@ -@import "@ckeditor/ckeditor5-ui/theme/mixins/_rwd.css"; - .ck.ck-math-form { - display: flex; - align-items: flex-start; - flex-direction: row; - flex-wrap: nowrap; + display: flex; + align-items: flex-start; + flex-direction: row; + flex-wrap: nowrap; - @mixin ck-media-phone { + @media screen and (max-width: 600px) { flex-wrap: wrap; - & .ck-math-view { + & .ck-math-view { flex-basis: 100%; - & .ck-labeled-input { - flex-basis: 100%; - } + & .ck-labeled-input { + flex-basis: 100%; + } - & .ck-label { - flex-basis: 100%; - } + & .ck-label { + flex-basis: 100%; + } } & .ck-button { @@ -27,7 +25,7 @@ } } -// Increase toolbar default z-index by one because math preview should be below of it +/* Increase toolbar default z-index by one because math preview should be below of it */ .ck.ck-toolbar-container { z-index: calc(var(--ck-z-modal) + 2); }