mirror of
https://github.com/TriliumNext/Notes.git
synced 2025-07-27 10:02:59 +08:00
Add '_regroup/ckeditor5-math/' from commit '6231df7f0e9df7f4d6982b103c02400d4f0b8937'
git-subtree-dir: _regroup/ckeditor5-math git-subtree-mainline: 034cd58833a2c9c7ba49f6217dc5aeff274e0174 git-subtree-split: 6231df7f0e9df7f4d6982b103c02400d4f0b8937
This commit is contained in:
commit
78544e5c99
20
_regroup/ckeditor5-math/.editorconfig
Normal file
20
_regroup/ckeditor5-math/.editorconfig
Normal file
@ -0,0 +1,20 @@
|
||||
root = true
|
||||
|
||||
[*]
|
||||
indent_style = tab
|
||||
tab_width = 4
|
||||
charset = utf-8
|
||||
end_of_line = lf
|
||||
trim_trailing_whitespace = true
|
||||
insert_final_newline = true
|
||||
|
||||
[*.{js,jsx,ts}]
|
||||
quote_type = single
|
||||
|
||||
[*.{yml,yaml}]
|
||||
indent_style = space
|
||||
indent_size = 4
|
||||
|
||||
[package.json]
|
||||
indent_style = space
|
||||
tab_width = 4
|
60
_regroup/ckeditor5-math/.eslintrc.cjs
Normal file
60
_regroup/ckeditor5-math/.eslintrc.cjs
Normal file
@ -0,0 +1,60 @@
|
||||
module.exports = {
|
||||
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,
|
||||
},
|
||||
ignorePatterns: [
|
||||
// Ignore the entire `build/` (the DLL build).
|
||||
"build/**",
|
||||
// Ignore compiled JavaScript files, as they are generated automatically.
|
||||
'src/**/*.js',
|
||||
// Also, do not check typing declarations, too.
|
||||
'src/**/*.d.ts'
|
||||
],
|
||||
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",
|
||||
|
||||
// This rule could not be found ???
|
||||
"ckeditor5-rules/use-require-for-debug-mode-imports": "off",
|
||||
|
||||
"no-void": ["error", { allowAsStatement: true }],
|
||||
},
|
||||
overrides: [
|
||||
{
|
||||
files: [ 'tests/**/*.[jt]s', 'sample/**/*.[jt]s' ],
|
||||
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",
|
||||
},
|
||||
},
|
||||
{
|
||||
env: {
|
||||
node: true,
|
||||
},
|
||||
files: [".eslintrc.{js,cjs}"],
|
||||
parserOptions: {
|
||||
sourceType: "script",
|
||||
},
|
||||
},
|
||||
],
|
||||
};
|
18
_regroup/ckeditor5-math/.gitattributes
vendored
Normal file
18
_regroup/ckeditor5-math/.gitattributes
vendored
Normal file
@ -0,0 +1,18 @@
|
||||
* text=auto
|
||||
|
||||
*.htaccess eol=lf
|
||||
*.cgi eol=lf
|
||||
*.sh eol=lf
|
||||
|
||||
*.css text
|
||||
*.htm text
|
||||
*.html text
|
||||
*.js text
|
||||
*.json text
|
||||
*.php text
|
||||
*.txt text
|
||||
*.md text
|
||||
|
||||
*.png -text
|
||||
*.gif -text
|
||||
*.jpg -text
|
26
_regroup/ckeditor5-math/.github/workflows/release.yml
vendored
Normal file
26
_regroup/ckeditor5-math/.github/workflows/release.yml
vendored
Normal file
@ -0,0 +1,26 @@
|
||||
name: Release
|
||||
on:
|
||||
push:
|
||||
tags:
|
||||
- 'v*'
|
||||
jobs:
|
||||
publish-package:
|
||||
name: Publish package
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- name: Set up Node
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: 22
|
||||
registry-url: 'https://registry.npmjs.org'
|
||||
always-auth: true
|
||||
- run: |
|
||||
corepack enable &&
|
||||
corepack install
|
||||
- name: Install dependencies
|
||||
run: yarn install --frozen-lockfile
|
||||
- name: Publish package
|
||||
run: yarn publish --access public
|
||||
env:
|
||||
NODE_AUTH_TOKEN: ${{secrets.NPM_TOKEN}}
|
10
_regroup/ckeditor5-math/.gitignore
vendored
Normal file
10
_regroup/ckeditor5-math/.gitignore
vendored
Normal file
@ -0,0 +1,10 @@
|
||||
node_modules/
|
||||
build/
|
||||
tmp/
|
||||
sample/ckeditor.dist.js
|
||||
package-lock.json
|
||||
yarn-error.log
|
||||
|
||||
# Ignore compiled TypeScript files.
|
||||
src/**/*.js
|
||||
src/**/*.d.ts
|
1
_regroup/ckeditor5-math/.nvmrc
Normal file
1
_regroup/ckeditor5-math/.nvmrc
Normal file
@ -0,0 +1 @@
|
||||
18.12.1
|
1
_regroup/ckeditor5-math/.prettierignore
Normal file
1
_regroup/ckeditor5-math/.prettierignore
Normal file
@ -0,0 +1 @@
|
||||
src/
|
11
_regroup/ckeditor5-math/.prettierrc
Normal file
11
_regroup/ckeditor5-math/.prettierrc
Normal file
@ -0,0 +1,11 @@
|
||||
{
|
||||
"embeddedLanguageFormatting": "off",
|
||||
"overrides": [
|
||||
{
|
||||
"files": "*.json",
|
||||
"options": {
|
||||
"tabWidth": 2
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
3
_regroup/ckeditor5-math/.stylelintrc
Normal file
3
_regroup/ckeditor5-math/.stylelintrc
Normal file
@ -0,0 +1,3 @@
|
||||
{
|
||||
"extends": "stylelint-config-ckeditor5"
|
||||
}
|
556
_regroup/ckeditor5-math/CHANGELOG.md
Normal file
556
_regroup/ckeditor5-math/CHANGELOG.md
Normal file
@ -0,0 +1,556 @@
|
||||
# Changelog
|
||||
|
||||
## Current
|
||||
|
||||
- Add latest changes here
|
||||
|
||||
## [43.2.0](https://github.com/isaul32/ckeditor5-math/compare/v43.1.2...v43.2.0) (2024-10-14)
|
||||
|
||||
- Update dependencies for CKEditor 43.2.0 ([Release
|
||||
notes](https://github.com/ckeditor/ckeditor5/blob/v43.2.0/CHANGELOG.md))
|
||||
([#153](https://github.com/isaul32/ckeditor5-math/pull/153))
|
||||
|
||||
**Note** This does **not** yet support the [new installation method](https://ckeditor.com/docs/ckeditor5/latest/updating/nim-migration/migration-to-new-installation-methods.html) for [custom plugins](https://ckeditor.com/docs/ckeditor5/latest/updating/nim-migration/custom-plugins.html). That will come in a future release.
|
||||
|
||||
## [43.1.2](https://github.com/isaul32/ckeditor5-math/compare/v43.1.1...v43.1.2) (2024-09-26)
|
||||
|
||||
- Downgrade ckeditor5-package-tools from 2 to 1. Fixes test for now.
|
||||
|
||||
## [43.1.1](https://github.com/isaul32/ckeditor5-math/compare/v41.4.2...v43.1.1) (2024-09-26)
|
||||
|
||||
- Update dependencies for CKEditor 43.1.1 ([Release
|
||||
notes](https://github.com/ckeditor/ckeditor5/blob/v43.1.1/CHANGELOG.md))
|
||||
([#149](https://github.com/isaul32/ckeditor5-math/pull/149))
|
||||
|
||||
**Note** This does **not** yet support the [new installation method](https://ckeditor.com/docs/ckeditor5/latest/updating/nim-migration/migration-to-new-installation-methods.html) for [custom plugins](https://ckeditor.com/docs/ckeditor5/latest/updating/nim-migration/custom-plugins.html). That will come in a future release.
|
||||
|
||||
- Move tests to TypeScript, kudos @fedemp
|
||||
([#135](https://github.com/isaul32/ckeditor5-math/pull/135))
|
||||
|
||||
## [41.4.2](https://github.com/isaul32/ckeditor5-math/compare/v41.3.1...v41.4.2) (2024-05-18)
|
||||
|
||||
- Update dependencies for CKEditor 41.4.2 ([Release
|
||||
notes](https://github.com/ckeditor/ckeditor5/blob/v41.4.2/CHANGELOG.md))
|
||||
([#141](https://github.com/isaul32/ckeditor5-math/pull/141))
|
||||
|
||||
## [41.3.1](https://github.com/isaul32/ckeditor5-math/compare/v41.3.0...v41.3.1) (2024-04-16)
|
||||
|
||||
- Update dependencies for CKEditor 41.3.1 ([Release
|
||||
notes](https://github.com/ckeditor/ckeditor5/blob/v41.3.1/CHANGELOG.md))
|
||||
([#137](https://github.com/isaul32/ckeditor5-math/pull/137))
|
||||
|
||||
## [41.3.0](https://github.com/isaul32/ckeditor5-math/compare/v41.2.3...v41.3.0) (2024-04-12)
|
||||
|
||||
- Update dependencies for CKEditor 41.3.0 ([Release
|
||||
notes](https://github.com/ckeditor/ckeditor5/blob/v41.3.0/CHANGELOG.md))
|
||||
(#136)
|
||||
|
||||
## [41.2.3](https://github.com/isaul32/ckeditor5-math/compare/v41.2.2...v41.2.3) (2024-03-22)
|
||||
|
||||
- Update dependencies for CKEditor 41.2.1 ([Release
|
||||
notes](https://github.com/ckeditor/ckeditor5/blob/v41.2.1/CHANGELOG.md))
|
||||
(#134)
|
||||
|
||||
## [41.2.2](https://github.com/isaul32/ckeditor5-math/compare/v41.2.1...v41.2.2) (2024-03-17)
|
||||
|
||||
- README updates ([#133](https://github.com/isaul32/ckeditor5-math/pull/133)):
|
||||
|
||||
- Note plugin supports DLL-based builds and is in TypeScript.
|
||||
- Remove old TypeScript workaround sections.
|
||||
|
||||
- Chore: Typo fixes ([#133](https://github.com/isaul32/ckeditor5-math/pull/133))
|
||||
|
||||
## [41.2.1](https://github.com/isaul32/ckeditor5-math/compare/v41.2.0...v41.2.1) (2024-03-17)
|
||||
|
||||
- Rewritten in TypeScript, credit @fedemp
|
||||
([#130](https://github.com/isaul32/ckeditor5-math/pull/130)).
|
||||
|
||||
## [41.2.0](https://github.com/isaul32/ckeditor5-math/compare/v41.1.0...v41.2.0) (2024-03-08)
|
||||
|
||||
- Update dependencies for CKEditor 41.2.0 ([Release
|
||||
notes](https://github.com/ckeditor/ckeditor5/blob/v41.2.0/CHANGELOG.md))
|
||||
(#129)
|
||||
|
||||
## [41.1.0](https://github.com/isaul32/ckeditor5-math/compare/v41.0.0...v41.1.0) (2024-02-13)
|
||||
|
||||
- Update dependencies for CKEditor 41.1.0 ([Release
|
||||
notes](https://github.com/ckeditor/ckeditor5/blob/v41.1.0/CHANGELOG.md))
|
||||
(#124)
|
||||
|
||||
## [41.0.0](https://github.com/isaul32/ckeditor5-math/compare/v40.2.0...v41.0.0) (2024-01-27)
|
||||
|
||||
- Update dependencies for CKEditor 41.0.0 ([Release
|
||||
notes](https://github.com/ckeditor/ckeditor5/blob/v41.0.0/CHANGELOG.md))
|
||||
(#122)
|
||||
- ui(CSS): Update `--ck-z-modal` to `--ck-z-panel` for CKEditor5 v41.0.0 (#122)
|
||||
|
||||
## [40.2.0](https://github.com/isaul32/ckeditor5-math/compare/v40.1.0...v40.2.0) (2023-12-12)
|
||||
|
||||
- Update dependencies for CKEditor 40.2.0 ([Release
|
||||
notes](https://github.com/ckeditor/ckeditor5/blob/v40.2.0/CHANGELOG.md))
|
||||
(#121)
|
||||
|
||||
## [40.1.0](https://github.com/isaul32/ckeditor5-math/compare/v40.0.0...v40.1.0) (2023-11-17)
|
||||
|
||||
- Update dependencies for CKEditor 40.1.0 ([Release
|
||||
notes](https://github.com/ckeditor/ckeditor5/blob/v40.1.0/CHANGELOG.md))
|
||||
(#120)
|
||||
|
||||
## [40.0.0](https://github.com/isaul32/ckeditor5-math/compare/v39.0.2...v40.0.0) (2023-10-13)
|
||||
|
||||
- Update dependencies for CKEditor 40.0.0 ([Release
|
||||
notes](https://github.com/ckeditor/ckeditor5/blob/v40.0.0/CHANGELOG.md))
|
||||
(#116)
|
||||
- Bump minimum Node.js version to 18+ per CKEditor 40 requirements (#116)
|
||||
|
||||
## [39.0.2](https://github.com/isaul32/ckeditor5-math/compare/v39.0.1...v39.0.2) (2023-09-06)
|
||||
|
||||
- Update dependencies for CKEditor 39.0.2 ([Release
|
||||
notes](https://github.com/ckeditor/ckeditor5/blob/v39.0.2/CHANGELOG.md))
|
||||
(#115)
|
||||
- Update lint packages (#115):
|
||||
|
||||
- eslint-config-ckeditor5: ^5.0.1 → ^5.1.1
|
||||
- stylelint-config-ckeditor5: >=4.1.1 → >=5.1.1
|
||||
|
||||
## [39.0.1](https://github.com/isaul32/ckeditor5-math/compare/v39.0.0...v39.0.1) (2023-08-10)
|
||||
|
||||
- Update dependencies for CKEditor 39.0.1 ([Release
|
||||
notes](https://github.com/ckeditor/ckeditor5/blob/v39.0.1/CHANGELOG.md))
|
||||
(#113)
|
||||
|
||||
## [39.0.0](https://github.com/isaul32/ckeditor5-math/compare/v38.1.1...v39.0.0) (2023-08-10)
|
||||
|
||||
- Update dependencies for CKEditor 39.0.0 ([Release
|
||||
notes](https://github.com/ckeditor/ckeditor5/blob/v39.0.0/CHANGELOG.md))
|
||||
(#112)
|
||||
|
||||
## [38.1.1](https://github.com/isaul32/ckeditor5-math/compare/v38.1.0...v38.1.1) (2023-07-26)
|
||||
|
||||
- Update dependencies for CKEditor 38.1.1 ([Release
|
||||
notes](https://github.com/ckeditor/ckeditor5/blob/v38.1.1/CHANGELOG.md))
|
||||
(#109)
|
||||
|
||||
## [38.1.0](https://github.com/isaul32/ckeditor5-math/compare/v38.0.1...v38.1.0) (2023-07-26)
|
||||
|
||||
- Update dependencies for CKEditor 38.1.0 ([Release
|
||||
notes](https://github.com/ckeditor/ckeditor5/blob/v38.1.0/CHANGELOG.md))
|
||||
(#108)
|
||||
|
||||
- Version updates (#106, #108)
|
||||
|
||||
- ckeditor5-package-tools: v1.0.0-beta.10 -> v1.1.0
|
||||
([release
|
||||
notes](https://github.com/ckeditor/ckeditor5-package-generator/blob/v1.1.0/CHANGELOG.md))
|
||||
- eslint-config-ckeditor5: >=4.1.1 -> ^5.0.1
|
||||
([release
|
||||
notes](https://github.com/ckeditor/ckeditor5-linters-config/blob/v5.1.0/CHANGELOG.md))
|
||||
|
||||
- README: Note typing workaround for TypeScript builds (#105)
|
||||
|
||||
1. Create a `d.ts` declaration file, e.g. `typings/ckeditor5-math.d.ts`
|
||||
|
||||
```typescript
|
||||
declare module '@isaul32/ckeditor5-math';
|
||||
declare module '@isaul32/ckeditor5-math/src/math';
|
||||
declare module '@isaul32/ckeditor5-math/src/autoformatmath';
|
||||
```
|
||||
|
||||
2. In your [`tsconfig.json`](https://www.typescriptlang.org/tsconfig)'s
|
||||
root-level [`include`](https://www.typescriptlang.org/tsconfig#include)
|
||||
option, make sure your declaration file is covered, e.g.
|
||||
|
||||
```json
|
||||
{
|
||||
"extends": "ckeditor5/tsconfig.json",
|
||||
"include": [
|
||||
"src",
|
||||
"typings",
|
||||
"../../typings"
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
## [38.0.1](https://github.com/isaul32/ckeditor5-math/compare/v38.0.0...v38.0.1) (2023-06-20)
|
||||
|
||||
- Update dependencies for CKEditor 38.0.1 ([Release
|
||||
notes](https://github.com/ckeditor/ckeditor5/blob/v38.0.1/CHANGELOG.md))
|
||||
|
||||
## [38.0.0](https://github.com/isaul32/ckeditor5-math/compare/v37.1.0...v38.0.0) (2023-06-20)
|
||||
|
||||
- Update dependencies for CKEditor 38.0.0 ([Release
|
||||
notes](https://github.com/ckeditor/ckeditor5/blob/v38.0.0/CHANGELOG.md))
|
||||
|
||||
## [37.1.0](https://github.com/isaul32/ckeditor5-math/compare/v37.0.2...v37.1.0) (2023-04-19)
|
||||
|
||||
- Update dependencies for CKEditor 37.1.0 ([Release
|
||||
notes](https://github.com/ckeditor/ckeditor5/blob/v37.1.0/CHANGELOG.md))
|
||||
|
||||
## [37.0.2](https://github.com/isaul32/ckeditor5-math/compare/v37.0.1...v37.0.2) (2023-04-05)
|
||||
|
||||
- Fix loading of ckeditor5-math when no config object is declared in build
|
||||
(#98)
|
||||
|
||||
## [37.0.1](https://github.com/isaul32/ckeditor5-math/compare/v37.0.0...v36.0.1) (2023-04-05)
|
||||
|
||||
- Update dependencies for CKEditor 37.0.1 ([Release
|
||||
notes](https://github.com/ckeditor/ckeditor5/blob/v37.0.1/CHANGELOG.md))
|
||||
|
||||
## [37.0.0](https://github.com/isaul32/ckeditor5-math/compare/v36.0.6...v37.0.0) (2023-04-05)
|
||||
|
||||
- Update dependencies for CKEditor 37.0.0 ([Release
|
||||
notes](https://github.com/ckeditor/ckeditor5/blob/v37.0.0/CHANGELOG.md))
|
||||
- Bump minimum node version to v16 (per CKEditor v37's requirements)
|
||||
- Add a .nvmrc for nvm users
|
||||
|
||||
## [36.0.7](https://github.com/isaul32/ckeditor5-math/compare/v36.0.6...v36.0.7) (2023-04-05)
|
||||
|
||||
- Fix loading of ckeditor5-math when no config object is declared in build
|
||||
(#97)
|
||||
|
||||
## [36.0.6](https://github.com/isaul32/ckeditor5-math/compare/v36.0.5...v36.0.6) (2023-04-05)
|
||||
|
||||
- :arrow_up: CKEditor package tools: 1.0.0-beta.8 -> beta.10
|
||||
|
||||
See also: https://github.com/ckeditor/ckeditor5-package-generator/blob/v1.0.0-beta.10/CHANGELOG.md
|
||||
|
||||
## [36.0.5](https://github.com/isaul32/ckeditor5-math/compare/v36.0.4...v36.0.5) (2023-04-03)
|
||||
|
||||
- Update docs for new package name (#91)
|
||||
|
||||
- Old: ckeditor5-math
|
||||
- New: @isaul32/ckeditor5-math
|
||||
|
||||
- New feature: Make className of span element configurable (#82, thank you
|
||||
@DanielKulbe)
|
||||
|
||||
## [36.0.4](https://github.com/isaul32/ckeditor5-math/compare/v36.0.3...v36.0.4) (2023-03-13)
|
||||
|
||||
- New package name
|
||||
|
||||
- Old: ckeditor5-math
|
||||
- New: @isaul32/ckeditor5-math
|
||||
|
||||
## [36.0.3](https://github.com/isaul32/ckeditor5-math/compare/v36.0.2...v36.0.3) (2023-03-13)
|
||||
|
||||
- Move to a DLL compatible plugin (#83)
|
||||
|
||||
Credit: @DanielKulbe
|
||||
|
||||
## [36.0.2](https://github.com/isaul32/ckeditor5-math/compare/v36.0.1...v36.0.2) (2023-02-14)
|
||||
|
||||
- Fix `previewClassName` (#86)
|
||||
|
||||
## [36.0.1](https://github.com/isaul32/ckeditor5-math/compare/v36.0.0...v36.0.1) (2023-01-26)
|
||||
|
||||
- Update dependencies for CKEditor 36.0.1 ([Release
|
||||
notes](https://github.com/ckeditor/ckeditor5/blob/v36.0.1/CHANGELOG.md))
|
||||
|
||||
## [36.0.0](https://github.com/isaul32/ckeditor5-math/compare/v35.4.0...v36.0.0) (2023-01-26)
|
||||
|
||||
- Update dependencies for CKEditor 36.0.0 ([Release
|
||||
notes](https://github.com/ckeditor/ckeditor5/blob/v36.0.0/CHANGELOG.md))
|
||||
|
||||
## [35.4.0](https://github.com/isaul32/ckeditor5-math/compare/v35.3.2...v35.4.0) (2022-12-13)
|
||||
|
||||
- Update dependencies for CKEditor 35.4.0 ([Release
|
||||
notes](https://github.com/ckeditor/ckeditor5/blob/v35.4.0/CHANGELOG.md))
|
||||
|
||||
## [35.3.2](https://github.com/isaul32/ckeditor5-math/compare/v35.3.1...v35.3.2) (2022-11-23)
|
||||
|
||||
- Update dependencies for CKEditor 35.3.2 ([Release
|
||||
notes](https://github.com/ckeditor/ckeditor5/blob/v35.3.2/CHANGELOG.md))
|
||||
|
||||
## [35.3.1](https://github.com/isaul32/ckeditor5-math/compare/v35.3.0...v35.3.1) (2022-11-15)
|
||||
|
||||
- Update dependencies for CKEditor 35.3.1 ([Release
|
||||
notes](https://github.com/ckeditor/ckeditor5/blob/v35.3.1/CHANGELOG.md))
|
||||
|
||||
## [35.3.0](https://github.com/isaul32/ckeditor5-math/compare/v35.2.1...v35.3.0) (2022-11-03)
|
||||
|
||||
- Update dependencies for CKEditor 35.3.0 ([Release
|
||||
notes](https://github.com/ckeditor/ckeditor5/blob/v35.3.0/CHANGELOG.md))
|
||||
|
||||
## [35.2.1](https://github.com/isaul32/ckeditor5-math/compare/v35.2.0...v35.2.1) (2022-10-13)
|
||||
|
||||
- Update dependencies for CKEditor 35.2.1 ([Release
|
||||
notes](https://github.com/ckeditor/ckeditor5/blob/v35.2.1/CHANGELOG.md))
|
||||
|
||||
## [35.2.0](https://github.com/isaul32/ckeditor5-math/compare/v35.1.0...v35.2.0) (2022-10-13)
|
||||
|
||||
- Update dependencies for CKEditor 35.2.0 ([Release
|
||||
notes](https://github.com/ckeditor/ckeditor5/blob/v35.2.0/CHANGELOG.md))
|
||||
|
||||
## [35.1.0](https://github.com/isaul32/ckeditor5-math/compare/v35.0.1...v35.1.0) (2022-09-28)
|
||||
|
||||
- Update dependencies for CKEditor 35.1.0 ([Release
|
||||
notes](https://github.com/ckeditor/ckeditor5/blob/v35.1.0/CHANGELOG.md))
|
||||
|
||||
## [35.0.1](https://github.com/isaul32/ckeditor5-math/compare/v35.0.0...v35.0.1) (2022-09-28)
|
||||
|
||||
- Update dependencies for CKEditor 35.0.1 ([Release
|
||||
notes](https://github.com/ckeditor/ckeditor5/blob/v35.0.1/CHANGELOG.md))
|
||||
|
||||
## [35.0.0](https://github.com/isaul32/ckeditor5-math/compare/v34.2.0...v35.0.0) (2022-09-28)
|
||||
|
||||
- Update dependencies for CKEditor 35.0.0 ([Release
|
||||
notes](https://github.com/ckeditor/ckeditor5/blob/v35.0.0/CHANGELOG.md))
|
||||
|
||||
## [34.2.0](https://github.com/isaul32/ckeditor5-math/compare/v34.1.1...v34.2.0) (2022-09-28)
|
||||
|
||||
- Update dependencies for CKEditor 34.2.0 ([Release
|
||||
notes](https://github.com/ckeditor/ckeditor5/blob/v34.2.0/CHANGELOG.md))
|
||||
|
||||
## [34.1.1](https://github.com/isaul32/ckeditor5-math/compare/v34.1.0...v34.1.1) (2022-08-03)
|
||||
|
||||
- New configuration setting, `katexRenderOptions` (optional) - for KaTeX engines. Accepts object of `katex.render()` / `katex.renderToString()` [options](https://katex.org/docs/options.html):
|
||||
|
||||
```js
|
||||
InlineEditor.defaultConfig = {
|
||||
// ...
|
||||
math: {
|
||||
engine: 'katex'
|
||||
katexRenderOptions: {
|
||||
macros: {
|
||||
"\\neq": "\\mathrel{\\char`≠}",
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
via PR [#64](https://github.com/isaul32/ckeditor5-math/pull/64) by [Tony
|
||||
Narlock](https://www.git-pull.com).
|
||||
|
||||
## [34.1.0](https://github.com/isaul32/ckeditor5-math/compare/v34.0.0...v34.1.0) (2022-06-21)
|
||||
|
||||
- Update dependencies for CKEditor 34.1.0 ([Release
|
||||
notes](https://github.com/ckeditor/ckeditor5/blob/v34.1.0/CHANGELOG.md))
|
||||
- Changelog:
|
||||
- Begin adding dates to releases
|
||||
- Remove _(current)_, which was being applied to old releases incorrectly up to last release
|
||||
|
||||
## [34.0.0](https://github.com/isaul32/ckeditor5-math/compare/v33.0.0...v34.0.0) (2022-05-12)
|
||||
|
||||
- Update dependencies for CKEditor 34.0.0 ([Release
|
||||
notes](https://github.com/ckeditor/ckeditor5/blob/v34.0.0/CHANGELOG.md))
|
||||
|
||||
- Begin keeping a yarn lockfile. This will make it easier to track changes
|
||||
aren't due to sub-dependencies shifting across time and development
|
||||
conditions.
|
||||
|
||||
## [33.0.0](https://github.com/isaul32/ckeditor5-math/compare/v32.0.0...v33.0.0)
|
||||
|
||||
- Update dependencies for CKEditor 33.0.0 ([Release
|
||||
notes](https://github.com/ckeditor/ckeditor5/blob/v33.0.0/CHANGELOG.md))
|
||||
|
||||
## [32.0.0](https://github.com/isaul32/ckeditor5-math/compare/v31.1.0...v32.0.0)
|
||||
|
||||
- Update dependencies for CKEditor 32.0.0 ([Release
|
||||
notes](https://github.com/ckeditor/ckeditor5/blob/v32.0.0/CHANGELOG.md))
|
||||
- Update webpack, postcss-loader, mini-css-extract-plugin, minimum node version (12 to 14)
|
||||
per above.
|
||||
|
||||
## [31.1.0](https://github.com/isaul32/ckeditor5-math/compare/v31.0.0...v31.1.0)
|
||||
|
||||
- Update dependencies for CKEditor 31.1.0 ([Release
|
||||
notes](https://github.com/ckeditor/ckeditor5/blob/v31.1.0/CHANGELOG.md))
|
||||
|
||||
## [31.0.0](https://github.com/isaul32/ckeditor5-math/compare/v30.0.0...v31.0.0)
|
||||
|
||||
- Update dependencies for CKEditor 31.0.0 ([Release
|
||||
notes](https://github.com/ckeditor/ckeditor5/blob/v31.0.0/CHANGELOG.md))
|
||||
|
||||
## [30.0.0](https://github.com/isaul32/ckeditor5-math/compare/v29.2.0...v30.0.0)
|
||||
|
||||
- Update dependencies for CKEditor 30.0.0 ([Release
|
||||
notes](https://github.com/ckeditor/ckeditor5/blob/v30.0.0/CHANGELOG.md))
|
||||
|
||||
## [29.2.0](https://github.com/isaul32/ckeditor5-math/compare/v29.1.0...v29.2.0)
|
||||
|
||||
- Update dependencies for CKEditor 29.2.0 ([Release
|
||||
notes](https://github.com/ckeditor/ckeditor5/blob/v29.2.0/CHANGELOG.md))
|
||||
- Fix `yarn start`'s missing classic editor dependency
|
||||
|
||||
## [29.1.0](https://github.com/isaul32/ckeditor5-math/compare/v29.0.0...v29.1.0)
|
||||
|
||||
- Update dependencies for CKEditor 29.1.0 ([Release
|
||||
notes](https://github.com/ckeditor/ckeditor5/blob/v29.1.0/CHANGELOG.md))
|
||||
|
||||
## [29.0.0](https://github.com/isaul32/ckeditor5-math/compare/v28.0.0...v29.0.0)
|
||||
|
||||
- Update dependencies for CKEditor 29.0.0 ([Release
|
||||
notes](https://github.com/ckeditor/ckeditor5/blob/v29.0.0/CHANGELOG.md))
|
||||
|
||||
## [28.0.0](https://github.com/isaul32/ckeditor5-math/compare/v27.1.4...v28.0.0)
|
||||
|
||||
- Update dependencies for CKEditor 28.0.0 ([Release
|
||||
notes](https://github.com/ckeditor/ckeditor5/releases/tag/v28.0.0))
|
||||
|
||||
## [27.1.4](https://github.com/isaul32/ckeditor5-math/compare/v27.1.3...v27.1.4)
|
||||
|
||||
- #45: docs(README,CHANGELOG): Format with prettier 2.3.0
|
||||
- #42: use `SwitchButton` to toggle "display mode". Thanks you @Jules-Bertholet!
|
||||
|
||||
## [27.1.3](https://github.com/isaul32/ckeditor5-math/compare/v27.1.2...27.1.3) (2021-05-16)
|
||||
|
||||
- #41: Prevent inserting empty equations, thank you @Jules-Bertholet.
|
||||
|
||||
## [27.1.2](https://github.com/isaul32/ckeditor5-math/compare/v27.1.1...v27.1.2) (2021-03-29)
|
||||
|
||||
- #38: You can now boot into a development instance with `yarn start` (supports
|
||||
live reload)
|
||||
- #40 (fixed #39): Support for upcasting Quill style tags
|
||||
|
||||
## [27.1.1](https://github.com/isaul32/ckeditor5-math/compare/v27.1.0...v27.1.1) (2021-03-29)
|
||||
|
||||
- Update dependencies for CKEditor 27.1.0 ([Release
|
||||
notes](https://github.com/ckeditor/ckeditor5/releases/tag/v27.1.0))
|
||||
|
||||
## [27.1.0](https://github.com/isaul32/ckeditor5-math/compare/v27.0.1...v27.1.0) (2021-03-29)
|
||||
|
||||
- #33: New optional config variables: `previewClassName` and `popupClassName` as an array
|
||||
of classes, this makes it easier to style the preview:
|
||||
|
||||
```javascript
|
||||
{
|
||||
"math": {
|
||||
"popupClassName": ["myeditor"],
|
||||
"previewClassName": ["myeditor"]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
This assures the preview appended to `document.body` and the popup both are
|
||||
accessible via `.myeditor`.
|
||||
|
||||
## [27.0.1](https://github.com/isaul32/ckeditor5-math/compare/v27.0.0...v27.0.1) (2021-03-29)
|
||||
|
||||
- Typo fix from #32.
|
||||
|
||||
## [27.0.0](https://github.com/isaul32/ckeditor5-math/compare/v26.0.0...v27.0.0) (2021-03-29)
|
||||
|
||||
- Update dependencies.
|
||||
|
||||
## [26.0.0](https://github.com/isaul32/ckeditor5-math/compare/v25.0.0...v26.0.0) (2021-03-04)
|
||||
|
||||
- Update dependencies.
|
||||
|
||||
## [25.0.0](https://github.com/isaul32/ckeditor5-math/compare/v24.0.1...v25.0.0) (2021-03-02)
|
||||
|
||||
- Update dependencies.
|
||||
|
||||
## [24.0.1](https://github.com/isaul32/ckeditor5-math/compare/24.0.0...v24.0.1) (2021-02-28)
|
||||
|
||||
- Fix balloon view position.
|
||||
|
||||
## [24.0.0](https://github.com/isaul32/ckeditor5-math/compare/v23.3.0...24.0.0) (2020-12-12)
|
||||
|
||||
- Update dependencies.
|
||||
|
||||
## [23.3.0](https://github.com/isaul32/ckeditor5-math/compare/23.2.2...v23.3.0) (2020-11-07)
|
||||
|
||||
- Add autoformat support. ([3354872](https://github.com/isaul32/ckeditor5-math/commit/3354872))
|
||||
|
||||
## [23.2.2](https://github.com/isaul32/ckeditor5-math/compare/v23.2.1...23.2.2) (2020-11-03)
|
||||
|
||||
- Fix placeholder handling. ([dc288ea](https://github.com/isaul32/ckeditor5-math/commit/dc288ea))
|
||||
- Fix selection after entering inline expression. ([2fea2e2](https://github.com/isaul32/ckeditor5-math/commit/2fea2e2))
|
||||
|
||||
## [23.2.1](https://github.com/isaul32/ckeditor5-math/compare/v23.2.0...v23.2.1) (2020-10-18)
|
||||
|
||||
- Fix math editing button for balloon editor. ([3629401](https://github.com/isaul32/ckeditor5-math/commit/3629401))
|
||||
|
||||
## [23.2.0](https://github.com/isaul32/ckeditor5-math/compare/v23.1.0...v23.2.0) (2020-10-18)
|
||||
|
||||
- Add math editing button for balloon editor. ([aa0392c](https://github.com/isaul32/ckeditor5-math/commit/aa0392c))
|
||||
|
||||
## [23.1.0](https://github.com/isaul32/ckeditor5-math/compare/v23.0.0...v23.1.0) (2020-10-11)
|
||||
|
||||
- Add typesetting auto load feature. ([a665b64](https://github.com/isaul32/ckeditor5-math/commit/a665b64))
|
||||
|
||||
## [23.0.0](https://github.com/isaul32/ckeditor5-math/compare/v22.0.0...v23.0.0) (2020-10-02)
|
||||
|
||||
- Update dependencies.
|
||||
|
||||
## [22.0.0](https://github.com/isaul32/ckeditor5-math/compare/v21.0.0...v22.0.0) (2020-08-29)
|
||||
|
||||
- Separate schema to display and inline.
|
||||
|
||||
### Bug fixes
|
||||
|
||||
- Fix writer. ([7d0cd01](https://github.com/isaul32/ckeditor5-math/commit/7d0cd01))
|
||||
|
||||
### Other changes
|
||||
|
||||
- Update dependencies.
|
||||
|
||||
## [21.0.0](https://github.com/isaul32/ckeditor5-math/compare/v20.0.0...v21.0.0) (2020-08-03)
|
||||
|
||||
- Update dependencies.
|
||||
|
||||
## [20.0.0](https://github.com/isaul32/ckeditor5-math/compare/v19.0.0...v20.0.0) (2020-07-13)
|
||||
|
||||
- Update dependencies.
|
||||
|
||||
## [19.0.0](https://github.com/isaul32/ckeditor5-math/compare/v18.0.1...v19.0.0) (2020-05-12)
|
||||
|
||||
- Update dependencies.
|
||||
|
||||
## [18.0.1](https://github.com/isaul32/ckeditor5-math/compare/v18.0.0...v18.0.1) (2020-04-05)
|
||||
|
||||
### Bug fixes
|
||||
|
||||
- Fix spacebar before formula bug in Firefox. [isaul32/ckeditor5-math#2](https://github.com/isaul32/ckeditor5-math/issues/2). ([9d15010](https://github.com/isaul32/ckeditor5-math/commit/9d15010))
|
||||
|
||||
## [18.0.0](https://github.com/isaul32/ckeditor5-math/compare/v17.0.1...v18.0.0) (2020-03-30)
|
||||
|
||||
- Update dependencies.
|
||||
|
||||
## [17.0.1](https://github.com/isaul32/ckeditor5-math/compare/v17.0.0...v17.0.1) (2020-02-27)
|
||||
|
||||
### Bug fixes
|
||||
|
||||
- Fix missing dependencies.
|
||||
|
||||
## [17.0.0](https://github.com/isaul32/ckeditor5-math/compare/v1.0.3...v17.0.0) (2020-02-27)
|
||||
|
||||
### Bug fixes
|
||||
|
||||
- Fix dependencies resolving problem. Closes [isaul32/ckeditor5-math#1](https://github.com/isaul32/ckeditor5-math/issues/1). ([7d40a2c](https://github.com/isaul32/ckeditor5-math/commit/7d40a2c))
|
||||
|
||||
## [1.0.3](https://github.com/isaul32/ckeditor5-math/compare/v1.0.2...v1.0.3) (2019-10-11)
|
||||
|
||||
### Bug fixes
|
||||
|
||||
- Fix preview flickering effect. ([70fefa8](https://github.com/isaul32/ckeditor5-math/commit/70fefa8))
|
||||
|
||||
- Fix disabled eslint lines. ([1f96286](https://github.com/isaul32/ckeditor5-math/commit/1f96286))
|
||||
|
||||
### Other changes
|
||||
|
||||
- Update some tests.
|
||||
|
||||
- Update readme.
|
||||
|
||||
## [1.0.2](https://github.com/isaul32/ckeditor5-math/compare/v1.0.1...v1.0.2) (2019-10-07)
|
||||
|
||||
### Other changes
|
||||
|
||||
- Update readme.
|
||||
|
||||
- Add unique identifier for math preview. ([8b6804c](https://github.com/isaul32/ckeditor5-math/commit/98815fc))
|
||||
|
||||
## [1.0.1](https://github.com/isaul32/ckeditor5-math/compare/v1.0.0...v1.0.1) (2019-10-04)
|
||||
|
||||
### Bug fixes
|
||||
|
||||
- Fix preview rendering bug. ([070f84e](https://github.com/isaul32/ckeditor5-math/commit/070f84e))
|
||||
|
||||
### Other changes
|
||||
|
||||
- Remove paste from office dependency. ([8b6804c](https://github.com/isaul32/ckeditor5-math/commit/8b6804c))
|
||||
|
||||
## [1.0.0](https://github.com/isaul32/ckeditor5-math/compare/v1.0.0...v1.0.0) (2019-10-03)
|
||||
|
||||
Initial release.
|
13
_regroup/ckeditor5-math/LICENSE
Normal file
13
_regroup/ckeditor5-math/LICENSE
Normal file
@ -0,0 +1,13 @@
|
||||
Copyright 2019 Sauli Anto
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
288
_regroup/ckeditor5-math/README.md
Normal file
288
_regroup/ckeditor5-math/README.md
Normal file
@ -0,0 +1,288 @@
|
||||
# CKEditor 5 mathematical feature · [](https://github.com/isaul32/ckeditor5-math/blob/master/LICENSE) [](https://www.npmjs.com/package/@isaul32/ckeditor5-math)
|
||||
|
||||
ckeditor5-math is a TeX-based mathematical plugin for CKEditor 5. You can use it to insert, edit, and view mathematical equations and formulas. This plugin supports [MathJax], [KaTeX] and custom typesetting engines.
|
||||
|
||||
[mathjax]: https://www.mathjax.org/
|
||||
[katex]: https://katex.org/
|
||||
|
||||
## Table of contents
|
||||
|
||||
- [Features](#features)
|
||||
- [Demos](#demos)
|
||||
- [Screenshots](#screenshots)
|
||||
- [Requirements](#requirements)
|
||||
- [Examples](#examples)
|
||||
- [Installation](#installation)
|
||||
- [Styles for Lark theme](#styles-for-lark-theme)
|
||||
- [Configuration & Usage](#configuration--usage)
|
||||
- [Plugin options](#plugin-options)
|
||||
- [Available typesetting engines](#available-typesetting-engines)
|
||||
- [Supported input and output formats](#supported-input-and-output-formats)
|
||||
- [Paste support](#paste-support)
|
||||
- [From plain text](#from-plain-text)
|
||||
- [Autoformat support](#autoformat-support)
|
||||
- [Preview workaround](#preview-workaround)
|
||||
|
||||
## Features
|
||||
|
||||
- Written in TypeScript (as of v41.2.1)
|
||||
- DLL build support (as of v36.0.3)
|
||||
- TeX syntax
|
||||
- Inline and display equations
|
||||
- Preview view
|
||||
- Multiple typesetting engines
|
||||
- Have multiple input and output format
|
||||
- Paste support
|
||||
- from plain text
|
||||
- Autoformat support
|
||||
|
||||
# Demos
|
||||
|
||||
- [Classic editor with MathJax](https://jsfiddle.net/isaul32/qktj9h7x/)
|
||||
- [Classic editor with KaTex](https://jsfiddle.net/isaul32/3wjrkLdv/)
|
||||
- [Balloon block editor with KaTex](https://jsfiddle.net/isaul32/q01mu8kp/)
|
||||
|
||||
## Screenshots
|
||||
|
||||

|
||||
|
||||

|
||||
|
||||
## Requirements
|
||||
|
||||
- Use same major version as your CKEditor 5 build
|
||||
|
||||
If you get duplicated modules error, you have mismatching versions.
|
||||
|
||||
## Examples
|
||||
|
||||
[Link to examples repository](https://github.com/isaul32/ckeditor5-math-examples)
|
||||
|
||||
## Installation
|
||||
|
||||
Use official classic or inline build as a base:
|
||||
|
||||
- [CKEditor 5 classic editor build](https://github.com/ckeditor/ckeditor5/tree/master/packages/ckeditor5-build-classic)
|
||||
- [CKEditor 5 inline editor build](https://github.com/ckeditor/ckeditor5/tree/master/packages/ckeditor5-build-inline)
|
||||
|
||||
Install plugin with NPM or Yarn
|
||||
|
||||
`npm install @isaul32/ckeditor5-math --save-dev`
|
||||
|
||||
`yarn add @isaul32/ckeditor5-math --dev`
|
||||
|
||||
Add import into ckeditor.js file
|
||||
|
||||
```js
|
||||
import Math from '@isaul32/ckeditor5-math/src/math';
|
||||
import AutoformatMath from '@isaul32/ckeditor5-math/src/autoformatmath';
|
||||
```
|
||||
|
||||
Add it to built-in plugins
|
||||
|
||||
```js
|
||||
InlineEditor.builtinPlugins = [
|
||||
// ...
|
||||
Math,
|
||||
AutoformatMath
|
||||
];
|
||||
```
|
||||
|
||||
**Add math button to toolbar**
|
||||
|
||||
```js
|
||||
InlineEditor.defaultConfig = {
|
||||
toolbar: {
|
||||
items: [
|
||||
// ...
|
||||
'math'
|
||||
]
|
||||
}
|
||||
};
|
||||
```
|
||||
|
||||
### Styles for Lark theme
|
||||
|
||||
**Copy theme/ckeditor5-math folder** from [https://github.com/isaul32/ckeditor5/tree/master/packages/ckeditor5-theme-lark](https://github.com/isaul32/ckeditor5/tree/master/packages/ckeditor5-theme-lark) to your lark theme repository
|
||||
|
||||
### Using DLL builds
|
||||
|
||||
Use the [official DLL build](https://ckeditor.com/docs/ckeditor5/latest/installation/advanced/alternative-setups/dll-builds.html) and additionally load the math plugin:
|
||||
|
||||
```html
|
||||
<script src="path/to/node_modules/@isaul32/ckeditor5-math/build/math.js"></script>
|
||||
<script>
|
||||
CKEditor5.editorClassic.ClassicEditor
|
||||
.create(editorElement, {
|
||||
plugins: [
|
||||
CKEditor5.math.Math,
|
||||
...
|
||||
],
|
||||
...
|
||||
});
|
||||
</script>
|
||||
```
|
||||
|
||||
## Configuration & Usage
|
||||
|
||||
### Plugin options
|
||||
|
||||
```js
|
||||
InlineEditor.defaultConfig = {
|
||||
// ...
|
||||
math: {
|
||||
engine: 'mathjax', // or katex or function. E.g. (equation, element, display) => { ... }
|
||||
lazyLoad: undefined, // async () => { ... }, called once before rendering first equation if engine doesn't exist. After resolving promise, plugin renders equations.
|
||||
outputType: 'script', // or span
|
||||
className: 'math-tex', // class name to use with span output type, change e.g. MathJax processClass (v2) / processHtmlClass (v3) is set
|
||||
forceOutputType: false, // forces output to use outputType
|
||||
enablePreview: true, // Enable preview view
|
||||
previewClassName: [], // Class names to add to previews
|
||||
popupClassName: [], // Class names to add to math popup balloon
|
||||
katexRenderOptions: {} // KaTeX only options for katex.render(ToString)
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Available typesetting engines
|
||||
|
||||
**MathJax**
|
||||
|
||||
- Tested with **latest 2.7**
|
||||
- Has experimental (**CHTML**, **SVG**) support for **3.0.0** or newer version
|
||||
|
||||
[<img src="https://www.mathjax.org/badge/badge-square.svg" width="130" alt="KaTeX">](https://www.mathjax.org/)
|
||||
|
||||
**KaTeX**
|
||||
|
||||
- Tested with version **0.12.0**
|
||||
|
||||
[<img src="https://katex.org/img/katex-logo-black.svg" width="130" alt="KaTeX">](https://katex.org/)
|
||||
|
||||
- `katexRenderOptions` - pass [options](https://katex.org/docs/options.html).
|
||||
|
||||
```js
|
||||
InlineEditor.defaultConfig = {
|
||||
// ...
|
||||
math: {
|
||||
engine: 'katex'
|
||||
katexRenderOptions: {
|
||||
macros: {
|
||||
"\\neq": "\\mathrel{\\char`≠}",
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**Custom typesetting**
|
||||
|
||||
Custom typesetting is possible to implement with engine config. For example, custom typesetting feature can be used when use back end rendering.
|
||||
|
||||
```js
|
||||
InlineEditor.defaultConfig = {
|
||||
// ...
|
||||
math: {
|
||||
engine: ( equation, element, display, preview ) => {
|
||||
// ...
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
- **equation** is equation in TeX format without delimiters.
|
||||
- **element** is DOM element reserved for rendering.
|
||||
- **display** is boolean. Typesetting should be inline when false.
|
||||
- **preview** is boolean. Rendering in preview when true.
|
||||
|
||||
### Supported input and output formats
|
||||
|
||||
Supported input and output formats are:
|
||||
|
||||
```html
|
||||
<!-- MathJax style http://docs.mathjax.org/en/v2.7-latest/advanced/model.html#how-mathematics-is-stored-in-the-page -->
|
||||
<script type="math/tex">\sqrt{\frac{a}{b}}</script>
|
||||
<script type="math/tex; mode=display">\sqrt{\frac{a}{b}}</script>
|
||||
|
||||
<!-- CKEditor 4 style https://ckeditor.com/docs/ckeditor4/latest/features/mathjax.html -->
|
||||
<span class="math-tex">\( \sqrt{\frac{a}{b}} \)</span>
|
||||
<span class="math-tex">\[ \sqrt{\frac{a}{b}} \]</span>
|
||||
```
|
||||
|
||||
### Paste support
|
||||
|
||||
#### From plain text
|
||||
|
||||
Paste TeX equations with **delimiters**. For example:
|
||||
|
||||
```latex
|
||||
\[ x=\frac{-b\pm\sqrt{b^2-4ac}}{2a} \]
|
||||
```
|
||||
|
||||
or
|
||||
|
||||
```latex
|
||||
\( x=\frac{-b\pm\sqrt{b^2-4ac}}{2a} \)
|
||||
```
|
||||
|
||||
### Autoformat support
|
||||
|
||||
#### Inline mode
|
||||
|
||||
Ctrl+M can be used to add easily math formulas in inline mode.
|
||||
|
||||
#### Display mode
|
||||
|
||||
Autoformat for math can be used to add formula in display mode on a new line by adding `\[` or `$$`. This feature requires additional autoformat plugin to be added.
|
||||
|
||||
Add following lines into your build
|
||||
|
||||
```js
|
||||
// ...
|
||||
import AutoformatMath from '@isaul32/ckeditor5-math/src/autoformatmath';
|
||||
|
||||
InlineEditor.builtinPlugins = [
|
||||
// ...
|
||||
AutoformatMath
|
||||
];
|
||||
```
|
||||
|
||||
or use it with DLL build
|
||||
|
||||
```html
|
||||
<script src="path/to/node_modules/@isaul32/ckeditor5-math/build/math.js"></script>
|
||||
<script>
|
||||
CKEditor5.editorInline.InlineEditorEditor
|
||||
.create(editorElement, {
|
||||
plugins: [
|
||||
CKEditor5.math.AutoformatMath,
|
||||
...
|
||||
],
|
||||
...
|
||||
});
|
||||
</script>
|
||||
```
|
||||
|
||||
## Preview workaround
|
||||
|
||||
`.ck-reset_all *` css rules from ckeditor5-ui and ckeditor5-theme-lark break rendering in preview mode.
|
||||
|
||||
My solution for this is use rendering element outside of CKEditor DOM and place it to right place by using absolute position. Alternative solution could be using iframe, but then typesetting engine's scripts and styles have to copy to child document.
|
||||
|
||||
## Development
|
||||
|
||||
Contributions, improvements and bug fixes are welcome. To aid in this, try out
|
||||
our developer environment w/ live reload support and [CKEditor 5 inspector].
|
||||
|
||||

|
||||
|
||||
To enter a development loop with hot reload support:
|
||||
|
||||
- `git clone https://github.com/isaul32/ckeditor5-math.git`
|
||||
- `cd ckeditor5-math`
|
||||
- `yarn`
|
||||
- `yarn start`
|
||||
- http://localhost:8080
|
||||
|
||||
[ckeditor 5 inspector]: https://ckeditor.com/docs/ckeditor5/latest/framework/guides/development-tools.html#ckeditor-5-inspector
|
23
_regroup/ckeditor5-math/ckeditor5-metadata.json
Normal file
23
_regroup/ckeditor5-math/ckeditor5-metadata.json
Normal file
@ -0,0 +1,23 @@
|
||||
{
|
||||
"plugins": [
|
||||
{
|
||||
"name": "Math",
|
||||
"className": "Math",
|
||||
"description": "Adds mathematical formulas to the editor.",
|
||||
"path": "src/math.js",
|
||||
"uiComponents": [
|
||||
{
|
||||
"name": "math",
|
||||
"type": "Button",
|
||||
"iconPath": "theme/icons/math.svg"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "AutoformatMath",
|
||||
"className": "AutoformatMath",
|
||||
"description": "Implements autoformatting with mathematical formulas.",
|
||||
"path": "src/autoformatmath.js"
|
||||
}
|
||||
]
|
||||
}
|
92
_regroup/ckeditor5-math/package.json
Normal file
92
_regroup/ckeditor5-math/package.json
Normal file
@ -0,0 +1,92 @@
|
||||
{
|
||||
"name": "@triliumnext/ckeditor5-math",
|
||||
"version": "43.2.0-hotfix1",
|
||||
"description": "Math feature for CKEditor 5.",
|
||||
"keywords": [
|
||||
"ckeditor",
|
||||
"ckeditor5",
|
||||
"ckeditor 5",
|
||||
"ckeditor5-feature",
|
||||
"ckeditor5-plugin",
|
||||
"ckeditor5-math",
|
||||
"katex"
|
||||
],
|
||||
"main": "src/index.js",
|
||||
"dependencies": {
|
||||
"@ckeditor/ckeditor5-core": "43.2.0",
|
||||
"@ckeditor/ckeditor5-enter": "43.2.0",
|
||||
"@ckeditor/ckeditor5-typing": "43.2.0",
|
||||
"@ckeditor/ckeditor5-ui": "43.2.0",
|
||||
"@ckeditor/ckeditor5-utils": "43.2.0",
|
||||
"ckeditor5": "43.2.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@ckeditor/ckeditor5-basic-styles": "43.2.0",
|
||||
"@ckeditor/ckeditor5-dev-utils": "^43.0.0",
|
||||
"@ckeditor/ckeditor5-editor-classic": "43.2.0",
|
||||
"@ckeditor/ckeditor5-engine": "43.2.0",
|
||||
"@ckeditor/ckeditor5-heading": "43.2.0",
|
||||
"@ckeditor/ckeditor5-image": "43.2.0",
|
||||
"@ckeditor/ckeditor5-list": "43.2.0",
|
||||
"@ckeditor/ckeditor5-paragraph": "43.2.0",
|
||||
"@ckeditor/ckeditor5-table": "43.2.0",
|
||||
"@ckeditor/ckeditor5-theme-lark": "43.2.0",
|
||||
"typescript": "5.0.4",
|
||||
"webpack": "^5.94.0",
|
||||
"webpack-cli": "^5.1.4"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=18.0.0",
|
||||
"npm": ">=5.7.1"
|
||||
},
|
||||
"author": "Sauli Anto",
|
||||
"license": "ISC",
|
||||
"bugs": "https://github.com/TriliumNext/ckeditor5-math/issues",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/TriliumNext/ckeditor5-math.git"
|
||||
},
|
||||
"files": [
|
||||
"lang",
|
||||
"src/**/*.js",
|
||||
"src/**/*.d.ts",
|
||||
"build",
|
||||
"theme",
|
||||
"ckeditor5-metadata.json",
|
||||
"CHANGELOG.md"
|
||||
],
|
||||
"scripts": {
|
||||
"ts:build": "tsc -p ./tsconfig.release.json",
|
||||
"ts:clear": "npx rimraf \"src/**/*.@(js|d.ts)\"",
|
||||
"dll:build": "ckeditor5-package-tools dll:build",
|
||||
"dll:serve": "http-server ./ -o sample/dll.html",
|
||||
"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",
|
||||
"prepublishOnly": "yarn run ts:build && ckeditor5-package-tools export-package-as-javascript",
|
||||
"postpublish": "yarn run ts:clear && ckeditor5-package-tools export-package-as-typescript",
|
||||
"start": "ckeditor5-package-tools start"
|
||||
},
|
||||
"lint-staged": {
|
||||
"**/*.ts": [
|
||||
"eslint --quiet"
|
||||
],
|
||||
"**/*.css": [
|
||||
"stylelint --quiet --allow-empty-input"
|
||||
]
|
||||
},
|
||||
"eslintIgnore": [
|
||||
"node_modules/**",
|
||||
"packages/*/node_modules/**",
|
||||
"packages/*/build/**",
|
||||
"packages/*/src/lib/**"
|
||||
],
|
||||
"husky": {
|
||||
"hooks": {
|
||||
"pre-commit": "lint-staged"
|
||||
}
|
||||
},
|
||||
"packageManager": "yarn@1.22.22"
|
||||
}
|
113
_regroup/ckeditor5-math/sample/ckeditor.js
vendored
Normal file
113
_regroup/ckeditor5-math/sample/ckeditor.js
vendored
Normal file
@ -0,0 +1,113 @@
|
||||
import ClassicEditor from '@ckeditor/ckeditor5-editor-classic/src/classiceditor';
|
||||
import CKEditorInspector from '@ckeditor/ckeditor5-inspector';
|
||||
|
||||
import Essentials from '@ckeditor/ckeditor5-essentials/src/essentials';
|
||||
import Autoformat from '@ckeditor/ckeditor5-autoformat/src/autoformat';
|
||||
import BlockQuote from '@ckeditor/ckeditor5-block-quote/src/blockquote';
|
||||
import Bold from '@ckeditor/ckeditor5-basic-styles/src/bold';
|
||||
import Heading from '@ckeditor/ckeditor5-heading/src/heading';
|
||||
import Image from '@ckeditor/ckeditor5-image/src/image';
|
||||
import ImageCaption from '@ckeditor/ckeditor5-image/src/imagecaption';
|
||||
import ImageStyle from '@ckeditor/ckeditor5-image/src/imagestyle';
|
||||
import ImageToolbar from '@ckeditor/ckeditor5-image/src/imagetoolbar';
|
||||
import ImageUpload from '@ckeditor/ckeditor5-image/src/imageupload';
|
||||
import Base64UploadAdapter from '@ckeditor/ckeditor5-upload/src/adapters/base64uploadadapter';
|
||||
import Indent from '@ckeditor/ckeditor5-indent/src/indent';
|
||||
import Italic from '@ckeditor/ckeditor5-basic-styles/src/italic';
|
||||
import Link from '@ckeditor/ckeditor5-link/src/link';
|
||||
import List from '@ckeditor/ckeditor5-list/src/list';
|
||||
import MediaEmbed from '@ckeditor/ckeditor5-media-embed/src/mediaembed';
|
||||
import Paragraph from '@ckeditor/ckeditor5-paragraph/src/paragraph';
|
||||
import Table from '@ckeditor/ckeditor5-table/src/table';
|
||||
import TableToolbar from '@ckeditor/ckeditor5-table/src/tabletoolbar';
|
||||
import CodeBlock from '@ckeditor/ckeditor5-code-block/src/codeblock';
|
||||
import Code from '@ckeditor/ckeditor5-basic-styles/src/code';
|
||||
|
||||
import { Math, AutoformatMath } from '../src/index';
|
||||
|
||||
/* global document, window */
|
||||
|
||||
ClassicEditor
|
||||
.create( document.querySelector( '#editor' ), {
|
||||
math: {
|
||||
engine: 'katex',
|
||||
katexRenderOptions: {
|
||||
macros: {
|
||||
'\\test': '\\mathrel{\\char`≠}'
|
||||
}
|
||||
}
|
||||
},
|
||||
plugins: [
|
||||
Math,
|
||||
AutoformatMath,
|
||||
Essentials,
|
||||
Autoformat,
|
||||
BlockQuote,
|
||||
Bold,
|
||||
Heading,
|
||||
Image,
|
||||
ImageCaption,
|
||||
ImageStyle,
|
||||
ImageToolbar,
|
||||
ImageUpload,
|
||||
Indent,
|
||||
Italic,
|
||||
Link,
|
||||
List,
|
||||
MediaEmbed,
|
||||
Paragraph,
|
||||
Table,
|
||||
TableToolbar,
|
||||
CodeBlock,
|
||||
Code,
|
||||
Base64UploadAdapter
|
||||
],
|
||||
toolbar: [
|
||||
'math',
|
||||
'|',
|
||||
'heading',
|
||||
'|',
|
||||
'bold',
|
||||
'italic',
|
||||
'link',
|
||||
'code',
|
||||
'bulletedList',
|
||||
'numberedList',
|
||||
'|',
|
||||
'outdent',
|
||||
'indent',
|
||||
'|',
|
||||
'uploadImage',
|
||||
'blockQuote',
|
||||
'insertTable',
|
||||
'mediaEmbed',
|
||||
'codeBlock',
|
||||
'|',
|
||||
'undo',
|
||||
'redo'
|
||||
],
|
||||
image: {
|
||||
toolbar: [
|
||||
'imageStyle:inline',
|
||||
'imageStyle:block',
|
||||
'imageStyle:side',
|
||||
'|',
|
||||
'imageTextAlternative'
|
||||
]
|
||||
},
|
||||
table: {
|
||||
contentToolbar: [
|
||||
'tableColumn',
|
||||
'tableRow',
|
||||
'mergeTableCells'
|
||||
]
|
||||
}
|
||||
} )
|
||||
.then( editor => {
|
||||
window.editor = editor;
|
||||
CKEditorInspector.attach( editor );
|
||||
window.console.log( 'CKEditor 5 is ready.', editor );
|
||||
} )
|
||||
.catch( err => {
|
||||
window.console.error( err.stack );
|
||||
} );
|
154
_regroup/ckeditor5-math/sample/dll.html
Normal file
154
_regroup/ckeditor5-math/sample/dll.html
Normal file
@ -0,0 +1,154 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<link rel="icon" type="image/png" href="https://ckeditor.com/docs/ckeditor5/latest/assets/img/favicons/32x32.png" sizes="32x32">
|
||||
<meta charset="utf-8">
|
||||
<title>CKEditor 5 with ckeditor5-math – DLL Sample</title>
|
||||
<link
|
||||
rel="stylesheet"
|
||||
href="https://cdn.jsdelivr.net/npm/katex@0.13.5/dist/katex.min.css"
|
||||
integrity="sha384-L+Gq2Cso/Y2x8fX4wausgiZT8z0QPZz7OqPuz4YqAycQJyrJT9NRLpjFBD6zlOia"
|
||||
crossorigin="anonymous"
|
||||
/>
|
||||
<script
|
||||
src="https://cdn.jsdelivr.net/npm/katex@0.13.5/dist/katex.min.js"
|
||||
integrity="sha384-z64WtjpyrKFsxox9eI4SI8eM9toXdoYeWb5Qh+8PO+eG54Bv9BZqf9xNhlcLf/sA"
|
||||
crossorigin="anonymous"
|
||||
></script>
|
||||
<script
|
||||
src="https://cdn.jsdelivr.net/npm/katex@0.13.5/dist/contrib/auto-render.min.js"
|
||||
integrity="sha384-vZTG03m+2yp6N6BNi5iM4rW4oIwk5DfcNdFfxkk9ZWpDriOkXX8voJBFrAO7MpVl"
|
||||
crossorigin="anonymous"
|
||||
onload="renderMathInElement(document.body, {'macros': {'\\test': '\\mathrel{\\char`≠}'}});"
|
||||
></script>
|
||||
<style>body { max-width: 800px; margin: 20px auto; }</style>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<h1>CKEditor 5 with ckeditor5-math – DLL Sample</h1>
|
||||
|
||||
<div id="editor">
|
||||
<h2>Production sample</h2>
|
||||
<p>
|
||||
This is a demo of the <a href="https://ckeditor.com/docs/ckeditor5/latest/builds/guides/overview.html#classic-editor">classic editor build</a> that loads the <code>Math</code> and <code>AutoformatMath</code> plugin.
|
||||
</p>
|
||||
<p>
|
||||
<code>Math</code> inserts mathematical formulas into the editor. You can click the CKEditor 5 Math icon in the toolbar and see the results.
|
||||
</p>
|
||||
<p><script type="math/tex">e=mc^2</script></p>
|
||||
<p><script type="math/tex; mode=display">e=mc^2</script></p>
|
||||
<p>
|
||||
This should show "\test" as ≠ via katexRenderOptions.macros:
|
||||
<script type="math/tex">\test</script>
|
||||
</p>
|
||||
<!-- Quill Style Tag -->
|
||||
<p><span class="ql-formula" data-value="e=mc^2"></span></p>
|
||||
</div>
|
||||
|
||||
<!-- DLL builds are served from the `node_modules/` directory -->
|
||||
<script src="../node_modules/ckeditor5/build/ckeditor5-dll.js"></script>
|
||||
<script src="../node_modules/@ckeditor/ckeditor5-editor-classic/build/editor-classic.js"></script>
|
||||
<script src="../node_modules/@ckeditor/ckeditor5-code-block/build/code-block.js"></script>
|
||||
<script src="../node_modules/@ckeditor/ckeditor5-essentials/build/essentials.js"></script>
|
||||
<script src="../node_modules/@ckeditor/ckeditor5-basic-styles/build/basic-styles.js"></script>
|
||||
<script src="../node_modules/@ckeditor/ckeditor5-heading/build/heading.js"></script>
|
||||
<script src="../node_modules/@ckeditor/ckeditor5-autoformat/build/autoformat.js"></script>
|
||||
<script src="../node_modules/@ckeditor/ckeditor5-block-quote/build/block-quote.js"></script>
|
||||
<script src="../node_modules/@ckeditor/ckeditor5-image/build/image.js"></script>
|
||||
<script src="../node_modules/@ckeditor/ckeditor5-link/build/link.js"></script>
|
||||
<script src="../node_modules/@ckeditor/ckeditor5-indent/build/indent.js"></script>
|
||||
<script src="../node_modules/@ckeditor/ckeditor5-media-embed/build/media-embed.js"></script>
|
||||
<script src="../node_modules/@ckeditor/ckeditor5-list/build/list.js"></script>
|
||||
<script src="../node_modules/@ckeditor/ckeditor5-table/build/table.js"></script>
|
||||
|
||||
<!-- The "ckeditor5-math" package DLL build is served from the `build/` directory -->
|
||||
<script src="../build/math.js"></script>
|
||||
|
||||
<script>
|
||||
console.log( 'Objects exported by the DLL build:', CKEditor5.math );
|
||||
|
||||
CKEditor5.editorClassic.ClassicEditor
|
||||
.create( document.querySelector( '#editor' ), {
|
||||
math: {
|
||||
engine: 'katex',
|
||||
katexRenderOptions: {
|
||||
macros: {
|
||||
'\\test': '\\mathrel{\\char`≠}'
|
||||
}
|
||||
}
|
||||
},
|
||||
plugins: [
|
||||
CKEditor5.math.Math,
|
||||
CKEditor5.math.AutoformatMath,
|
||||
CKEditor5.essentials.Essentials,
|
||||
CKEditor5.autoformat.Autoformat,
|
||||
CKEditor5.blockQuote.BlockQuote,
|
||||
CKEditor5.basicStyles.Bold,
|
||||
CKEditor5.heading.Heading,
|
||||
CKEditor5.image.Image,
|
||||
CKEditor5.image.ImageCaption,
|
||||
CKEditor5.image.ImageStyle,
|
||||
CKEditor5.image.ImageToolbar,
|
||||
CKEditor5.image.ImageUpload,
|
||||
CKEditor5.indent.Indent,
|
||||
CKEditor5.basicStyles.Italic,
|
||||
CKEditor5.link.Link,
|
||||
CKEditor5.list.List,
|
||||
CKEditor5.mediaEmbed.MediaEmbed,
|
||||
CKEditor5.paragraph.Paragraph,
|
||||
CKEditor5.table.Table,
|
||||
CKEditor5.table.TableToolbar,
|
||||
CKEditor5.codeBlock.CodeBlock,
|
||||
CKEditor5.basicStyles.Code,
|
||||
CKEditor5.upload.Base64UploadAdapter
|
||||
],
|
||||
toolbar: [
|
||||
'math',
|
||||
'|',
|
||||
'heading',
|
||||
'|',
|
||||
'bold',
|
||||
'italic',
|
||||
'link',
|
||||
'code',
|
||||
'bulletedList',
|
||||
'numberedList',
|
||||
'|',
|
||||
'outdent',
|
||||
'indent',
|
||||
'|',
|
||||
'uploadImage',
|
||||
'blockQuote',
|
||||
'insertTable',
|
||||
'mediaEmbed',
|
||||
'codeBlock',
|
||||
'|',
|
||||
'undo',
|
||||
'redo'
|
||||
],
|
||||
image: {
|
||||
toolbar: [
|
||||
'imageStyle:inline',
|
||||
'imageStyle:block',
|
||||
'imageStyle:side',
|
||||
'|',
|
||||
'imageTextAlternative'
|
||||
]
|
||||
},
|
||||
table: {
|
||||
contentToolbar: [
|
||||
'tableColumn',
|
||||
'tableRow',
|
||||
'mergeTableCells'
|
||||
]
|
||||
}
|
||||
} )
|
||||
.then( editor => {
|
||||
window.editor = editor;
|
||||
} )
|
||||
.catch( error => {
|
||||
console.error( 'There was a problem initializing the editor.', error );
|
||||
} );
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
90
_regroup/ckeditor5-math/sample/index.html
Normal file
90
_regroup/ckeditor5-math/sample/index.html
Normal file
@ -0,0 +1,90 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<link rel="icon" type="image/png" href="https://ckeditor.com/docs/ckeditor5/latest/assets/img/favicons/32x32.png" sizes="32x32">
|
||||
<meta charset="utf-8">
|
||||
<title>CKEditor 5 with ckeditor5-math – Development Sample</title>
|
||||
<link
|
||||
rel="stylesheet"
|
||||
href="https://cdn.jsdelivr.net/npm/katex@0.13.5/dist/katex.min.css"
|
||||
integrity="sha384-L+Gq2Cso/Y2x8fX4wausgiZT8z0QPZz7OqPuz4YqAycQJyrJT9NRLpjFBD6zlOia"
|
||||
crossorigin="anonymous"
|
||||
/>
|
||||
<script
|
||||
src="https://cdn.jsdelivr.net/npm/katex@0.13.5/dist/katex.min.js"
|
||||
integrity="sha384-z64WtjpyrKFsxox9eI4SI8eM9toXdoYeWb5Qh+8PO+eG54Bv9BZqf9xNhlcLf/sA"
|
||||
crossorigin="anonymous"
|
||||
></script>
|
||||
<script
|
||||
src="https://cdn.jsdelivr.net/npm/katex@0.13.5/dist/contrib/auto-render.min.js"
|
||||
integrity="sha384-vZTG03m+2yp6N6BNi5iM4rW4oIwk5DfcNdFfxkk9ZWpDriOkXX8voJBFrAO7MpVl"
|
||||
crossorigin="anonymous"
|
||||
onload="renderMathInElement(document.body, {'macros': {'\\test': '\\mathrel{\\char`≠}'}});"
|
||||
></script>
|
||||
<style>body { max-width: 800px; margin: 20px auto; }</style>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<h1>CKEditor 5 with ckeditor5-math – Development Sample</h1>
|
||||
|
||||
<div id="editor">
|
||||
<h2>Development environment</h2>
|
||||
<p>
|
||||
This is a demo of the <a href="https://ckeditor.com/docs/ckeditor5/latest/builds/guides/overview.html#classic-editor">classic editor build</a> that loads the <code>Math</code> and <code>AutoformatMath</code> plugin.
|
||||
</p>
|
||||
<p>
|
||||
<code>Math</code> inserts mathematical formulas into the editor. You can click the CKEditor 5 Math icon in the toolbar and see the results.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
<script type="math/tex">e=mc^2</script>
|
||||
</p>
|
||||
|
||||
<p>
|
||||
<script type="math/tex; mode=display">e=mc^2</script>
|
||||
</p>
|
||||
|
||||
<p>
|
||||
This should show "\test" as ≠ via katexRenderOptions.macros:
|
||||
<script type="math/tex">\test</script>
|
||||
</p>
|
||||
|
||||
<!-- Quill Style Tag -->
|
||||
<p>
|
||||
<span class="ql-formula" data-value="e=mc^2"></span>
|
||||
</p>
|
||||
|
||||
<h3>The directory structure</h3>
|
||||
|
||||
<p>
|
||||
The code snippet below presents the directory structure.
|
||||
</p>
|
||||
|
||||
<pre><code class="language-plaintext">.
|
||||
├─ sample
|
||||
│ ├─ dll.html # The editor initialized using the DLL builds. Check README for details.
|
||||
│ ├─ index.html # The currently displayed file.
|
||||
│ └─ ckeditor.js # The editor initialization script.
|
||||
├─ src
|
||||
│ ├─ autoformatmath.js # The AutoformatMath plugin.
|
||||
│ ├─ math.js # The Math plugin.
|
||||
│ ├─ index.js # The modules exported by the package when using the DLL builds.
|
||||
│ └─ **/*.js # JavaScript source files.
|
||||
├─ tests
|
||||
│ └─ **/*.js # Test files
|
||||
├─ theme
|
||||
│ ├─ icons
|
||||
│ │ ├─ math.svg # The Math icon displayed in the toolbar.
|
||||
│ └─ mathform.css # Math editor styles.
|
||||
├─ .editorconfig
|
||||
├─ ...
|
||||
└─ README.md</code></pre>
|
||||
|
||||
<h3>Reporting issues</h3>
|
||||
<p>If you found a problem with CKEditor 5 or the package generator, please, report an issue:</p>
|
||||
<p><a href="https://github.com/isaul32/ckeditor5-math/issues">CKEditor 5 Math</a></p>
|
||||
</div>
|
||||
|
||||
<script src="./ckeditor.dist.js"></script>
|
||||
</body>
|
||||
</html>
|
BIN
_regroup/ckeditor5-math/screenshots/1.png
Normal file
BIN
_regroup/ckeditor5-math/screenshots/1.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 25 KiB |
BIN
_regroup/ckeditor5-math/screenshots/2.png
Normal file
BIN
_regroup/ckeditor5-math/screenshots/2.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 16 KiB |
BIN
_regroup/ckeditor5-math/screenshots/development-environment.png
Normal file
BIN
_regroup/ckeditor5-math/screenshots/development-environment.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 36 KiB |
37
_regroup/ckeditor5-math/src/augmentation.ts
Normal file
37
_regroup/ckeditor5-math/src/augmentation.ts
Normal file
@ -0,0 +1,37 @@
|
||||
import Math from './math';
|
||||
import MathCommand from './mathcommand';
|
||||
import MathEditing from './mathediting';
|
||||
import MathUI from './mathui';
|
||||
import type { KatexOptions } from './typings-external';
|
||||
|
||||
declare module '@ckeditor/ckeditor5-core' {
|
||||
|
||||
interface PluginsMap {
|
||||
[ Math.pluginName ]: Math;
|
||||
[ MathEditing.pluginName ]: MathEditing;
|
||||
[ MathUI.pluginName ]: MathUI;
|
||||
}
|
||||
|
||||
interface CommandsMap {
|
||||
math: MathCommand;
|
||||
}
|
||||
|
||||
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;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
59
_regroup/ckeditor5-math/src/autoformatmath.ts
Normal file
59
_regroup/ckeditor5-math/src/autoformatmath.ts
Normal file
@ -0,0 +1,59 @@
|
||||
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 {
|
||||
public static get requires() {
|
||||
return [ Math, 'Autoformat' ] as const;
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public init(): void {
|
||||
const editor = this.editor;
|
||||
|
||||
if ( !editor.plugins.has( 'Math' ) ) {
|
||||
logWarning( 'autoformat-math-feature-missing', editor );
|
||||
}
|
||||
}
|
||||
|
||||
public afterInit(): void {
|
||||
const editor = this.editor;
|
||||
const command = editor.commands.get( 'math' );
|
||||
|
||||
if ( command instanceof MathCommand ) {
|
||||
const callback = () => {
|
||||
if ( !command.isEnabled ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
command.display = true;
|
||||
|
||||
// Wait until selection is removed.
|
||||
window.setTimeout(
|
||||
() => {
|
||||
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 );
|
||||
}
|
||||
}
|
||||
|
||||
public static get pluginName() {
|
||||
return 'AutoformatMath' as const;
|
||||
}
|
||||
}
|
137
_regroup/ckeditor5-math/src/automath.ts
Normal file
137
_regroup/ckeditor5-math/src/automath.ts
Normal file
@ -0,0 +1,137 @@
|
||||
import { Clipboard } from 'ckeditor5/src/clipboard';
|
||||
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 {
|
||||
public static get requires() {
|
||||
return [ Clipboard, Undo ] as const;
|
||||
}
|
||||
|
||||
public static get pluginName() {
|
||||
return 'AutoMath' as const;
|
||||
}
|
||||
|
||||
private _timeoutId: null | number;
|
||||
private _positionToInsert: null | LivePosition;
|
||||
|
||||
constructor( editor: Editor ) {
|
||||
super( editor );
|
||||
|
||||
this._timeoutId = null;
|
||||
|
||||
this._positionToInsert = null;
|
||||
}
|
||||
|
||||
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';
|
||||
|
||||
const rightLivePosition = LivePosition.fromPosition( firstRange.end );
|
||||
rightLivePosition.stickiness = 'toNext';
|
||||
|
||||
modelDocument.once( 'change:data', () => {
|
||||
this._mathBetweenPositions(
|
||||
leftLivePosition,
|
||||
rightLivePosition
|
||||
);
|
||||
|
||||
leftLivePosition.detach();
|
||||
rightLivePosition.detach();
|
||||
},
|
||||
{ priority: 'high' }
|
||||
);
|
||||
}
|
||||
);
|
||||
|
||||
editor.commands.get( 'undo' )?.on( 'execute', () => {
|
||||
if ( this._timeoutId ) {
|
||||
window.clearTimeout( this._timeoutId );
|
||||
this._positionToInsert?.detach();
|
||||
|
||||
this._timeoutId = null;
|
||||
this._positionToInsert = null;
|
||||
}
|
||||
}, { priority: 'high' } );
|
||||
}
|
||||
|
||||
private _mathBetweenPositions(
|
||||
leftPosition: LivePosition,
|
||||
rightPosition: LivePosition
|
||||
) {
|
||||
const editor = this.editor;
|
||||
|
||||
// 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 } );
|
||||
|
||||
let text = '';
|
||||
|
||||
// Get equation text
|
||||
for ( const node of walker ) {
|
||||
if ( node.item.is( '$textProxy' ) ) {
|
||||
text += node.item.data;
|
||||
}
|
||||
}
|
||||
|
||||
text = text.trim();
|
||||
|
||||
// Skip if don't have delimiters
|
||||
if ( !hasDelimiters( text ) || delimitersCounts( text ) !== 2 ) {
|
||||
return;
|
||||
}
|
||||
|
||||
const mathCommand = editor.commands.get( 'math' );
|
||||
|
||||
// Do not anything if math element cannot be inserted at the current position
|
||||
if ( !mathCommand?.isEnabled ) {
|
||||
return;
|
||||
}
|
||||
|
||||
this._positionToInsert = LivePosition.fromPosition( leftPosition );
|
||||
|
||||
// With timeout user can undo conversation if want use plain text
|
||||
this._timeoutId = window.setTimeout( () => {
|
||||
editor.model.change( writer => {
|
||||
this._timeoutId = null;
|
||||
|
||||
writer.remove( equationRange );
|
||||
|
||||
let insertPosition: LivePosition | null;
|
||||
|
||||
// Check if position where the math element should be inserted is still valid.
|
||||
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
|
||||
);
|
||||
|
||||
editor.model.insertContent( mathElement, insertPosition );
|
||||
|
||||
innerWriter.setSelection( mathElement, 'on' );
|
||||
} );
|
||||
|
||||
this._positionToInsert?.detach();
|
||||
this._positionToInsert = null;
|
||||
} );
|
||||
}, 100 );
|
||||
}
|
||||
}
|
8
_regroup/ckeditor5-math/src/index.ts
Normal file
8
_regroup/ckeditor5-math/src/index.ts
Normal file
@ -0,0 +1,8 @@
|
||||
/**
|
||||
* @module math
|
||||
*/
|
||||
|
||||
export { default as Math } from './math';
|
||||
export { default as AutoformatMath } from './autoformatmath';
|
||||
|
||||
import "./augmentation.js";
|
16
_regroup/ckeditor5-math/src/math.ts
Normal file
16
_regroup/ckeditor5-math/src/math.ts
Normal file
@ -0,0 +1,16 @@
|
||||
import { Plugin } from 'ckeditor5/src/core';
|
||||
import { Widget } from 'ckeditor5/src/widget';
|
||||
|
||||
import MathUI from './mathui';
|
||||
import MathEditing from './mathediting';
|
||||
import AutoMath from './automath';
|
||||
|
||||
export default class Math extends Plugin {
|
||||
public static get requires() {
|
||||
return [ MathEditing, MathUI, AutoMath, Widget ] as const;
|
||||
}
|
||||
|
||||
public static get pluginName() {
|
||||
return 'Math' as const;
|
||||
}
|
||||
}
|
64
_regroup/ckeditor5-math/src/mathcommand.ts
Normal file
64
_regroup/ckeditor5-math/src/mathcommand.ts
Normal file
@ -0,0 +1,64 @@
|
||||
import { Command } from 'ckeditor5/src/core';
|
||||
import { getSelectedMathModelWidget } from './utils';
|
||||
|
||||
export default class MathCommand extends Command {
|
||||
public override value: string | null = null;
|
||||
public override execute(
|
||||
equation: string,
|
||||
display?: boolean,
|
||||
outputType: 'script' | 'span' = 'script',
|
||||
forceOutputType?: boolean
|
||||
): void {
|
||||
const model = this.editor.model;
|
||||
const selection = model.document.selection;
|
||||
const selectedElement = selection.getSelectedElement();
|
||||
|
||||
model.change( writer => {
|
||||
let 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(
|
||||
display ? 'mathtex-display' : 'mathtex-inline',
|
||||
{ equation, type, display }
|
||||
);
|
||||
} else {
|
||||
// Create new model element
|
||||
mathtex = writer.createElement(
|
||||
display ? 'mathtex-display' : 'mathtex-inline',
|
||||
{ equation, type: outputType, display }
|
||||
);
|
||||
}
|
||||
model.insertContent( mathtex );
|
||||
} );
|
||||
}
|
||||
|
||||
public display = false;
|
||||
|
||||
public override refresh(): void {
|
||||
const model = this.editor.model;
|
||||
const selection = model.document.selection;
|
||||
const selectedElement = selection.getSelectedElement();
|
||||
|
||||
this.isEnabled =
|
||||
selectedElement === null ||
|
||||
selectedElement.is( 'element', 'mathtex-inline' ) ||
|
||||
selectedElement.is( 'element', 'mathtex-display' );
|
||||
|
||||
const selectedEquation = getSelectedMathModelWidget( selection );
|
||||
const value = selectedEquation?.getAttribute( 'equation' );
|
||||
this.value = typeof value === 'string' ? value : null;
|
||||
const display = selectedEquation?.getAttribute( 'display' );
|
||||
this.display = typeof display === 'boolean' ? display : false;
|
||||
}
|
||||
}
|
307
_regroup/ckeditor5-math/src/mathediting.ts
Normal file
307
_regroup/ckeditor5-math/src/mathediting.ts
Normal file
@ -0,0 +1,307 @@
|
||||
import MathCommand from './mathcommand';
|
||||
import { type Editor, Plugin } from 'ckeditor5/src/core';
|
||||
import {
|
||||
toWidget,
|
||||
Widget,
|
||||
viewToModelPositionOutsideModelElement
|
||||
} from 'ckeditor5/src/widget';
|
||||
import { renderEquation, extractDelimiters } from './utils';
|
||||
import type { DowncastWriter, Element } from 'ckeditor5/src/engine';
|
||||
import { CKEditorError, uid } from 'ckeditor5/src/utils';
|
||||
|
||||
export default class MathEditing extends Plugin {
|
||||
public static get requires() {
|
||||
return [ Widget ] as const;
|
||||
}
|
||||
|
||||
public static get pluginName() {
|
||||
return 'MathEditing' as const;
|
||||
}
|
||||
|
||||
constructor( editor: Editor ) {
|
||||
super( editor );
|
||||
editor.config.define( 'math', {
|
||||
engine: 'mathjax',
|
||||
outputType: 'script',
|
||||
className: 'math-tex',
|
||||
forceOutputType: false,
|
||||
enablePreview: true,
|
||||
previewClassName: [],
|
||||
popupClassName: [],
|
||||
katexRenderOptions: {}
|
||||
} );
|
||||
}
|
||||
|
||||
public init(): void {
|
||||
const editor = this.editor;
|
||||
editor.commands.add( 'math', new MathCommand( editor ) );
|
||||
|
||||
this._defineSchema();
|
||||
this._defineConverters();
|
||||
|
||||
editor.editing.mapper.on(
|
||||
'viewToModelPosition',
|
||||
viewToModelPositionOutsideModelElement(
|
||||
editor.model,
|
||||
viewElement => viewElement.hasClass( 'math' )
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
private _defineSchema() {
|
||||
const schema = this.editor.model.schema;
|
||||
schema.register( 'mathtex-inline', {
|
||||
allowWhere: '$text',
|
||||
isInline: true,
|
||||
isObject: true,
|
||||
allowAttributes: [ 'equation', 'type', 'display' ]
|
||||
} );
|
||||
|
||||
schema.register( 'mathtex-display', {
|
||||
inheritAllFrom: '$blockObject',
|
||||
allowAttributes: [ 'equation', 'type', 'display' ]
|
||||
} );
|
||||
}
|
||||
|
||||
private _defineConverters() {
|
||||
const conversion = this.editor.conversion;
|
||||
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
||||
const mathConfig = this.editor.config.get( 'math' )!;
|
||||
|
||||
// View -> Model
|
||||
conversion
|
||||
.for( 'upcast' )
|
||||
// MathJax inline way (e.g. <script type="math/tex">\sqrt{\frac{a}{b}}</script>)
|
||||
.elementToElement( {
|
||||
view: {
|
||||
name: 'script',
|
||||
attributes: {
|
||||
type: 'math/tex'
|
||||
}
|
||||
},
|
||||
model: ( viewElement, { writer } ) => {
|
||||
const child = viewElement.getChild( 0 );
|
||||
if ( child?.is( '$text' ) ) {
|
||||
const equation = child.data.trim();
|
||||
return writer.createElement( 'mathtex-inline', {
|
||||
equation,
|
||||
type: mathConfig.forceOutputType ?
|
||||
mathConfig.outputType :
|
||||
'script',
|
||||
display: false
|
||||
} );
|
||||
}
|
||||
return null;
|
||||
}
|
||||
} )
|
||||
// MathJax display way (e.g. <script type="math/tex; mode=display">\sqrt{\frac{a}{b}}</script>)
|
||||
.elementToElement( {
|
||||
view: {
|
||||
name: 'script',
|
||||
attributes: {
|
||||
type: 'math/tex; mode=display'
|
||||
}
|
||||
},
|
||||
model: ( viewElement, { writer } ) => {
|
||||
const child = viewElement.getChild( 0 );
|
||||
if ( child?.is( '$text' ) ) {
|
||||
const equation = child.data.trim();
|
||||
return writer.createElement( 'mathtex-display', {
|
||||
equation,
|
||||
type: mathConfig.forceOutputType ?
|
||||
mathConfig.outputType :
|
||||
'script',
|
||||
display: true
|
||||
} );
|
||||
}
|
||||
return null;
|
||||
}
|
||||
} )
|
||||
// CKEditor 4 way (e.g. <span class="math-tex">\( \sqrt{\frac{a}{b}} \)</span>)
|
||||
.elementToElement( {
|
||||
view: {
|
||||
name: 'span',
|
||||
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
||||
classes: [ mathConfig.className! ]
|
||||
},
|
||||
model: ( viewElement, { writer } ) => {
|
||||
const child = viewElement.getChild( 0 );
|
||||
if ( child?.is( '$text' ) ) {
|
||||
const equation = child.data.trim();
|
||||
|
||||
const params = Object.assign( extractDelimiters( equation ), {
|
||||
type: mathConfig.forceOutputType ?
|
||||
mathConfig.outputType :
|
||||
'span'
|
||||
} );
|
||||
|
||||
return writer.createElement(
|
||||
params.display ? 'mathtex-display' : 'mathtex-inline',
|
||||
params
|
||||
);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
} )
|
||||
// KaTeX from Quill: https://github.com/quilljs/quill/blob/develop/formats/formula.js
|
||||
.elementToElement( {
|
||||
view: {
|
||||
name: 'span',
|
||||
classes: [ 'ql-formula' ]
|
||||
},
|
||||
model: ( viewElement, { writer } ) => {
|
||||
const equation = viewElement.getAttribute( 'data-value' );
|
||||
if ( equation == null ) {
|
||||
/**
|
||||
* Couldn't find equation on current element
|
||||
* @error missing-equation
|
||||
*/
|
||||
throw new CKEditorError( 'missing-equation', { pluginName: 'math' } );
|
||||
}
|
||||
return writer.createElement( 'mathtex-inline', {
|
||||
equation: equation.trim(),
|
||||
type: mathConfig.forceOutputType ?
|
||||
mathConfig.outputType :
|
||||
'script',
|
||||
display: false
|
||||
} );
|
||||
}
|
||||
} );
|
||||
|
||||
// Model -> View (element)
|
||||
conversion
|
||||
.for( 'editingDowncast' )
|
||||
.elementToElement( {
|
||||
model: 'mathtex-inline',
|
||||
view: ( modelItem, { writer } ) => {
|
||||
const widgetElement = createMathtexEditingView(
|
||||
modelItem,
|
||||
writer
|
||||
);
|
||||
return toWidget( widgetElement, writer );
|
||||
}
|
||||
} )
|
||||
.elementToElement( {
|
||||
model: 'mathtex-display',
|
||||
view: ( modelItem, { writer } ) => {
|
||||
const widgetElement = createMathtexEditingView(
|
||||
modelItem,
|
||||
writer
|
||||
);
|
||||
return toWidget( widgetElement, writer );
|
||||
}
|
||||
} );
|
||||
|
||||
// Model -> Data
|
||||
conversion
|
||||
.for( 'dataDowncast' )
|
||||
.elementToElement( {
|
||||
model: 'mathtex-inline',
|
||||
view: createMathtexView
|
||||
} )
|
||||
.elementToElement( {
|
||||
model: 'mathtex-display',
|
||||
view: createMathtexView
|
||||
} );
|
||||
|
||||
// Create view for editor
|
||||
function createMathtexEditingView(
|
||||
modelItem: Element,
|
||||
writer: DowncastWriter
|
||||
) {
|
||||
const equation = String( 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 = writer.createContainerElement(
|
||||
display ? 'div' : 'span',
|
||||
{
|
||||
style: styles,
|
||||
class: classes
|
||||
}
|
||||
);
|
||||
|
||||
const uiElement = writer.createUIElement(
|
||||
'div',
|
||||
null,
|
||||
function( domDocument ) {
|
||||
const domElement = this.toDomElement( domDocument );
|
||||
|
||||
void renderEquation(
|
||||
equation,
|
||||
domElement,
|
||||
mathConfig.engine,
|
||||
mathConfig.lazyLoad,
|
||||
display,
|
||||
false,
|
||||
`math-editing-${ uid() }`,
|
||||
mathConfig.previewClassName,
|
||||
mathConfig.katexRenderOptions
|
||||
);
|
||||
|
||||
return domElement;
|
||||
}
|
||||
);
|
||||
|
||||
writer.insert( writer.createPositionAt( mathtexView, 0 ), uiElement );
|
||||
|
||||
return mathtexView;
|
||||
}
|
||||
|
||||
// Create view for data
|
||||
function createMathtexView(
|
||||
modelItem: Element,
|
||||
{ writer }: { writer: DowncastWriter }
|
||||
) {
|
||||
const equation = modelItem.getAttribute( 'equation' );
|
||||
if ( typeof equation != 'string' ) {
|
||||
/**
|
||||
* Couldn't find equation on current element
|
||||
* @error missing-equation
|
||||
*/
|
||||
throw new CKEditorError( 'missing-equation', { pluginName: 'math' } );
|
||||
}
|
||||
|
||||
const type = modelItem.getAttribute( 'type' );
|
||||
const display = modelItem.getAttribute( 'display' );
|
||||
|
||||
if ( type === 'span' ) {
|
||||
const mathtexView = writer.createContainerElement( 'span', {
|
||||
class: mathConfig.className
|
||||
} );
|
||||
|
||||
if ( display ) {
|
||||
writer.insert(
|
||||
writer.createPositionAt( mathtexView, 0 ),
|
||||
writer.createText( '\\[' + equation + '\\]' )
|
||||
);
|
||||
} else {
|
||||
writer.insert(
|
||||
writer.createPositionAt( mathtexView, 0 ),
|
||||
writer.createText( '\\(' + equation + '\\)' )
|
||||
);
|
||||
}
|
||||
|
||||
return mathtexView;
|
||||
} else {
|
||||
const mathtexView = writer.createContainerElement( 'script', {
|
||||
type: display ? 'math/tex; mode=display' : 'math/tex'
|
||||
} );
|
||||
|
||||
writer.insert(
|
||||
writer.createPositionAt( mathtexView, 0 ),
|
||||
writer.createText( equation )
|
||||
);
|
||||
|
||||
return mathtexView;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
288
_regroup/ckeditor5-math/src/mathui.ts
Normal file
288
_regroup/ckeditor5-math/src/mathui.ts
Normal file
@ -0,0 +1,288 @@
|
||||
import MathEditing from './mathediting';
|
||||
import MainFormView from './ui/mainformview';
|
||||
import mathIcon from '../theme/icons/math.svg';
|
||||
import { Plugin } from 'ckeditor5/src/core';
|
||||
import { ClickObserver } from 'ckeditor5/src/engine';
|
||||
import {
|
||||
ButtonView,
|
||||
ContextualBalloon,
|
||||
clickOutsideHandler
|
||||
} from 'ckeditor5/src/ui';
|
||||
import { CKEditorError, global, uid } from 'ckeditor5/src/utils';
|
||||
import { getBalloonPositionData } from './utils';
|
||||
import MathCommand from './mathcommand';
|
||||
|
||||
const mathKeystroke = 'Ctrl+M';
|
||||
|
||||
export default class MathUI extends Plugin {
|
||||
public static get requires() {
|
||||
return [ ContextualBalloon, MathEditing ] as const;
|
||||
}
|
||||
|
||||
public static get pluginName() {
|
||||
return 'MathUI' as const;
|
||||
}
|
||||
|
||||
private _previewUid = `math-preview-${ uid() }`;
|
||||
private _balloon: ContextualBalloon = this.editor.plugins.get( ContextualBalloon );
|
||||
public formView: MainFormView | null = null;
|
||||
|
||||
public init(): void {
|
||||
const editor = this.editor;
|
||||
editor.editing.view.addObserver( ClickObserver );
|
||||
|
||||
this._createToolbarMathButton();
|
||||
|
||||
this.formView = this._createFormView();
|
||||
|
||||
this._enableUserBalloonInteractions();
|
||||
}
|
||||
|
||||
public override destroy(): void {
|
||||
super.destroy();
|
||||
|
||||
this.formView?.destroy();
|
||||
|
||||
// Destroy preview element
|
||||
const previewEl = document.getElementById( this._previewUid );
|
||||
if ( previewEl ) {
|
||||
previewEl.parentNode?.removeChild( previewEl );
|
||||
}
|
||||
}
|
||||
|
||||
public _showUI(): void {
|
||||
const editor = this.editor;
|
||||
const mathCommand = editor.commands.get( 'math' );
|
||||
|
||||
if ( !mathCommand?.isEnabled ) {
|
||||
return;
|
||||
}
|
||||
|
||||
this._addFormView();
|
||||
|
||||
this._balloon.showStack( 'main' );
|
||||
}
|
||||
|
||||
private _createFormView() {
|
||||
const editor = this.editor;
|
||||
const mathCommand = editor.commands.get( 'math' );
|
||||
if ( !( mathCommand instanceof MathCommand ) ) {
|
||||
/**
|
||||
* Missing Math command
|
||||
* @error math-command
|
||||
*/
|
||||
throw new CKEditorError( 'math-command' );
|
||||
}
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
||||
const mathConfig = editor.config.get( 'math' )!;
|
||||
|
||||
const formView = new MainFormView(
|
||||
editor.locale,
|
||||
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
||||
mathConfig.engine!,
|
||||
mathConfig.lazyLoad,
|
||||
mathConfig.enablePreview,
|
||||
this._previewUid,
|
||||
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
||||
mathConfig.previewClassName!,
|
||||
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
||||
mathConfig.popupClassName!,
|
||||
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
||||
mathConfig.katexRenderOptions!
|
||||
);
|
||||
|
||||
formView.mathInputView.bind( 'value' ).to( mathCommand, 'value' );
|
||||
formView.displayButtonView.bind( 'isOn' ).to( mathCommand, 'display' );
|
||||
|
||||
// Form elements should be read-only when corresponding commands are disabled.
|
||||
formView.mathInputView.bind( 'isReadOnly' ).to( mathCommand, 'isEnabled', value => !value );
|
||||
formView.saveButtonView.bind( 'isEnabled' ).to( mathCommand );
|
||||
formView.displayButtonView.bind( 'isEnabled' ).to( mathCommand );
|
||||
|
||||
// Listen to submit button click
|
||||
this.listenTo( formView, 'submit', () => {
|
||||
editor.execute( 'math', formView.equation, formView.displayButtonView.isOn, mathConfig.outputType, mathConfig.forceOutputType );
|
||||
this._closeFormView();
|
||||
} );
|
||||
|
||||
// Listen to cancel button click
|
||||
this.listenTo( formView, 'cancel', () => {
|
||||
this._closeFormView();
|
||||
} );
|
||||
|
||||
// Close plugin ui, if esc is pressed (while ui is focused)
|
||||
formView.keystrokes.set( 'esc', ( _data, cancel ) => {
|
||||
this._closeFormView();
|
||||
cancel();
|
||||
} );
|
||||
|
||||
return formView;
|
||||
}
|
||||
|
||||
private _addFormView() {
|
||||
if ( this._isFormInPanel ) {
|
||||
return;
|
||||
}
|
||||
|
||||
const editor = this.editor;
|
||||
const mathCommand = editor.commands.get( 'math' );
|
||||
if ( !( mathCommand instanceof MathCommand ) ) {
|
||||
/**
|
||||
* Math command not found
|
||||
* @error plugin-load
|
||||
*/
|
||||
throw new CKEditorError( 'plugin-load', { pluginName: 'math' } );
|
||||
}
|
||||
|
||||
if ( this.formView == null ) {
|
||||
return;
|
||||
}
|
||||
|
||||
this._balloon.add( {
|
||||
view: this.formView,
|
||||
position: getBalloonPositionData( editor )
|
||||
} );
|
||||
|
||||
if ( this._balloon.visibleView === this.formView ) {
|
||||
this.formView.mathInputView.fieldView.element?.select();
|
||||
}
|
||||
|
||||
// Show preview element
|
||||
const previewEl = document.getElementById( this._previewUid );
|
||||
if ( previewEl && this.formView.previewEnabled ) {
|
||||
// Force refresh preview
|
||||
this.formView.mathView?.updateMath();
|
||||
}
|
||||
|
||||
this.formView.equation = mathCommand.value ?? '';
|
||||
this.formView.displayButtonView.isOn = mathCommand.display || false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @private
|
||||
*/
|
||||
public _hideUI(): void {
|
||||
if ( !this._isFormInPanel ) {
|
||||
return;
|
||||
}
|
||||
|
||||
const editor = this.editor;
|
||||
|
||||
this.stopListening( editor.ui, 'update' );
|
||||
this.stopListening( this._balloon, 'change:visibleView' );
|
||||
|
||||
editor.editing.view.focus();
|
||||
|
||||
// Remove form first because it's on top of the stack.
|
||||
this._removeFormView();
|
||||
}
|
||||
|
||||
private _closeFormView() {
|
||||
const mathCommand = this.editor.commands.get( 'math' );
|
||||
if ( mathCommand?.value != null ) {
|
||||
this._removeFormView();
|
||||
} else {
|
||||
this._hideUI();
|
||||
}
|
||||
}
|
||||
|
||||
private _removeFormView() {
|
||||
if ( this._isFormInPanel && this.formView ) {
|
||||
this.formView.saveButtonView.focus();
|
||||
|
||||
this._balloon.remove( this.formView );
|
||||
|
||||
// Hide preview element
|
||||
const previewEl = document.getElementById( this._previewUid );
|
||||
if ( previewEl ) {
|
||||
previewEl.style.visibility = 'hidden';
|
||||
}
|
||||
|
||||
this.editor.editing.view.focus();
|
||||
}
|
||||
}
|
||||
|
||||
private _createToolbarMathButton() {
|
||||
const editor = this.editor;
|
||||
const mathCommand = editor.commands.get( 'math' );
|
||||
if ( !mathCommand ) {
|
||||
/**
|
||||
* Math command not found
|
||||
* @error plugin-load
|
||||
*/
|
||||
throw new CKEditorError( 'plugin-load', { pluginName: 'math' } );
|
||||
}
|
||||
const t = editor.t;
|
||||
|
||||
// Handle the `Ctrl+M` keystroke and show the panel.
|
||||
editor.keystrokes.set( mathKeystroke, ( _keyEvtData, cancel ) => {
|
||||
// Prevent focusing the search bar in FF and opening new tab in Edge. #153, #154.
|
||||
cancel();
|
||||
|
||||
if ( mathCommand.isEnabled ) {
|
||||
this._showUI();
|
||||
}
|
||||
} );
|
||||
|
||||
this.editor.ui.componentFactory.add( 'math', locale => {
|
||||
const button = new ButtonView( locale );
|
||||
|
||||
button.isEnabled = true;
|
||||
button.label = t( 'Insert math' );
|
||||
button.icon = mathIcon;
|
||||
button.keystroke = mathKeystroke;
|
||||
button.tooltip = true;
|
||||
button.isToggleable = true;
|
||||
|
||||
button.bind( 'isEnabled' ).to( mathCommand, 'isEnabled' );
|
||||
|
||||
this.listenTo( button, 'execute', () => {
|
||||
this._showUI();
|
||||
} );
|
||||
|
||||
return button;
|
||||
} );
|
||||
}
|
||||
|
||||
private _enableUserBalloonInteractions() {
|
||||
const editor = this.editor;
|
||||
const viewDocument = this.editor.editing.view.document;
|
||||
this.listenTo( viewDocument, 'click', () => {
|
||||
const mathCommand = editor.commands.get( 'math' );
|
||||
if ( mathCommand?.isEnabled && mathCommand.value ) {
|
||||
this._showUI();
|
||||
}
|
||||
} );
|
||||
|
||||
// Close the panel on the Esc key press when the editable has focus and the balloon is visible.
|
||||
editor.keystrokes.set( 'Esc', ( _data, cancel ) => {
|
||||
if ( this._isUIVisible ) {
|
||||
this._hideUI();
|
||||
cancel();
|
||||
}
|
||||
} );
|
||||
|
||||
// Close on click outside of balloon panel element.
|
||||
if ( this.formView ) {
|
||||
clickOutsideHandler( {
|
||||
emitter: this.formView,
|
||||
activator: () => !!this._isFormInPanel,
|
||||
contextElements: this._balloon.view.element ? [ this._balloon.view.element ] : [],
|
||||
callback: () => { this._hideUI(); }
|
||||
} );
|
||||
} else {
|
||||
throw new Error( 'missing form view' );
|
||||
}
|
||||
}
|
||||
|
||||
private get _isUIVisible() {
|
||||
const visibleView = this._balloon.visibleView;
|
||||
|
||||
return visibleView == this.formView;
|
||||
}
|
||||
|
||||
private get _isFormInPanel() {
|
||||
return this.formView && this._balloon.hasView( this.formView );
|
||||
}
|
||||
}
|
156
_regroup/ckeditor5-math/src/typings-external.ts
Normal file
156
_regroup/ckeditor5-math/src/typings-external.ts
Normal file
@ -0,0 +1,156 @@
|
||||
/**
|
||||
* Basic typings for third party, external libraries (KaTeX, MathJax).
|
||||
*/
|
||||
export interface MathJax3 {
|
||||
version: string;
|
||||
tex2chtmlPromise?: ( input: string, options: { display: boolean } ) => Promise<HTMLElement>;
|
||||
tex2svgPromise?: ( input: string, options: { display: boolean } ) => Promise<HTMLElement>;
|
||||
}
|
||||
|
||||
export interface MathJax2 {
|
||||
Hub: { Queue: ( callback: [string, MathJax2['Hub'], string | HTMLElement] | ( () => void ) ) => void };
|
||||
}
|
||||
|
||||
export interface Katex {
|
||||
render( equation: string, el: HTMLElement, options: KatexOptions ): void;
|
||||
}
|
||||
|
||||
declare global {
|
||||
// eslint-disable-next-line no-var
|
||||
var CKEDITOR_MATH_LAZY_LOAD: undefined | Promise<void>;
|
||||
// eslint-disable-next-line no-var
|
||||
var MathJax: undefined | MathJax2 | MathJax3;
|
||||
// eslint-disable-next-line no-var
|
||||
var katex: undefined | Katex;
|
||||
}
|
||||
|
||||
export interface KatexOptions {
|
||||
|
||||
/**
|
||||
* If `true`, math will be rendered in display mode
|
||||
* (math in display style and center math on page)
|
||||
*
|
||||
* If `false`, math will be rendered in inline mode
|
||||
* @default false
|
||||
*/
|
||||
displayMode?: boolean | undefined;
|
||||
|
||||
/**
|
||||
* Determines the markup language of the output. The valid choices are:
|
||||
* - `html`: Outputs KaTeX in HTML only.
|
||||
* - `mathml`: Outputs KaTeX in MathML only.
|
||||
* - `htmlAndMathml`: Outputs HTML for visual rendering
|
||||
* and includes MathML for accessibility.
|
||||
*
|
||||
* @default 'htmlAndMathml'
|
||||
*/
|
||||
output?: 'html' | 'mathml' | 'htmlAndMathml' | undefined;
|
||||
|
||||
/**
|
||||
* If `true`, display math has \tags rendered on the left
|
||||
* instead of the right, like \usepackage[leqno]{amsmath} in LaTeX.
|
||||
*
|
||||
* @default false
|
||||
*/
|
||||
leqno?: boolean | undefined;
|
||||
|
||||
/**
|
||||
* If `true`, display math renders flush left with a 2em left margin,
|
||||
* like \documentclass[fleqn] in LaTeX with the amsmath package.
|
||||
*
|
||||
* @default false
|
||||
*/
|
||||
fleqn?: boolean | undefined;
|
||||
|
||||
/**
|
||||
* If `true`, KaTeX will throw a `ParseError` when
|
||||
* it encounters an unsupported command or invalid LaTex
|
||||
*
|
||||
* If `false`, KaTeX will render unsupported commands as
|
||||
* text, and render invalid LaTeX as its source code with
|
||||
* hover text giving the error, in color given by errorColor
|
||||
* @default true
|
||||
*/
|
||||
throwOnError?: boolean | undefined;
|
||||
|
||||
/**
|
||||
* A Color string given in format `#XXX` or `#XXXXXX`
|
||||
*/
|
||||
errorColor?: string | undefined;
|
||||
|
||||
/**
|
||||
* A collection of custom macros.
|
||||
*
|
||||
* See `src/macros.js` for its usage
|
||||
*/
|
||||
macros?: unknown;
|
||||
|
||||
/**
|
||||
* Specifies a minimum thickness, in ems, for fraction lines,
|
||||
* \sqrt top lines, {array} vertical lines, \hline, \hdashline,
|
||||
* \underline, \overline, and the borders of \fbox, \boxed, and
|
||||
* \fcolorbox.
|
||||
*/
|
||||
minRuleThickness?: number | undefined;
|
||||
|
||||
/**
|
||||
* If `true`, `\color` will work like LaTeX's `\textcolor`
|
||||
* and takes 2 arguments
|
||||
*
|
||||
* If `false`, `\color` will work like LaTeX's `\color`
|
||||
* and takes 1 argument
|
||||
*
|
||||
* In both cases, `\textcolor` works as in LaTeX
|
||||
*
|
||||
* @default false
|
||||
*/
|
||||
colorIsTextColor?: boolean | undefined;
|
||||
|
||||
/**
|
||||
* All user-specified sizes will be caped to `maxSize` ems
|
||||
*
|
||||
* If set to Infinity, users can make elements and space
|
||||
* arbitrarily large
|
||||
*
|
||||
* @default Infinity
|
||||
*/
|
||||
maxSize?: number | undefined;
|
||||
|
||||
/**
|
||||
* Limit the number of macro expansions to specified number
|
||||
*
|
||||
* If set to `Infinity`, marco expander will try to fully expand
|
||||
* as in LaTex
|
||||
*
|
||||
* @default 1000
|
||||
*/
|
||||
maxExpand?: number | undefined;
|
||||
|
||||
/**
|
||||
* If `false` or `"ignore"`, allow features that make
|
||||
* writing in LaTex convenient but not supported by LaTex
|
||||
*
|
||||
* If `true` or `"error"`, throw an error for such transgressions
|
||||
*
|
||||
* If `"warn"`, warn about behavior via `console.warn`
|
||||
*
|
||||
* @default "warn"
|
||||
*/
|
||||
strict?: boolean | string | Function | undefined;
|
||||
|
||||
/**
|
||||
* If `false` (do not trust input), prevent any commands that could enable adverse behavior, rendering them instead in errorColor.
|
||||
*
|
||||
* If `true` (trust input), allow all such commands.
|
||||
*
|
||||
* @default false
|
||||
*/
|
||||
trust?: boolean | ( ( context: object ) => boolean ) | undefined;
|
||||
|
||||
/**
|
||||
* Place KaTeX code in the global group.
|
||||
*
|
||||
* @default false
|
||||
*/
|
||||
globalGroup?: boolean | undefined;
|
||||
}
|
284
_regroup/ckeditor5-math/src/ui/mainformview.ts
Normal file
284
_regroup/ckeditor5-math/src/ui/mainformview.ts
Normal file
@ -0,0 +1,284 @@
|
||||
import { icons } from 'ckeditor5/src/core';
|
||||
import {
|
||||
ButtonView,
|
||||
createLabeledInputText,
|
||||
FocusCycler,
|
||||
LabelView,
|
||||
LabeledFieldView,
|
||||
submitHandler,
|
||||
SwitchButtonView,
|
||||
View,
|
||||
ViewCollection,
|
||||
type InputTextView,
|
||||
type FocusableView
|
||||
} from 'ckeditor5/src/ui';
|
||||
import { Locale, FocusTracker, KeystrokeHandler } from 'ckeditor5/src/utils';
|
||||
import { extractDelimiters, hasDelimiters } from '../utils';
|
||||
import MathView from './mathview';
|
||||
import '../../theme/mathform.css';
|
||||
import type { KatexOptions } from '../typings-external';
|
||||
|
||||
const { check: checkIcon, cancel: cancelIcon } = icons;
|
||||
|
||||
class MathInputView extends LabeledFieldView<InputTextView> {
|
||||
public value: null | string = null;
|
||||
public isReadOnly = false;
|
||||
|
||||
constructor( locale: Locale ) {
|
||||
super( locale, createLabeledInputText );
|
||||
}
|
||||
}
|
||||
|
||||
export default class MainFormView extends View {
|
||||
public saveButtonView: ButtonView;
|
||||
public mathInputView: MathInputView;
|
||||
public displayButtonView: SwitchButtonView;
|
||||
public cancelButtonView: ButtonView;
|
||||
public previewEnabled: boolean;
|
||||
public previewLabel?: LabelView;
|
||||
public mathView?: MathView;
|
||||
public override locale: Locale = new Locale();
|
||||
public lazyLoad: undefined | ( () => Promise<void> );
|
||||
|
||||
constructor(
|
||||
locale: Locale,
|
||||
engine:
|
||||
| 'mathjax'
|
||||
| 'katex'
|
||||
| ( (
|
||||
equation: string,
|
||||
element: HTMLElement,
|
||||
display: boolean,
|
||||
) => void ),
|
||||
lazyLoad: undefined | ( () => Promise<void> ),
|
||||
previewEnabled = false,
|
||||
previewUid: string,
|
||||
previewClassName: Array<string>,
|
||||
popupClassName: Array<string>,
|
||||
katexRenderOptions: KatexOptions
|
||||
) {
|
||||
super( locale );
|
||||
|
||||
const t = locale.t;
|
||||
|
||||
// Submit button
|
||||
this.saveButtonView = this._createButton( t( 'Save' ), checkIcon, 'ck-button-save', null );
|
||||
this.saveButtonView.type = 'submit';
|
||||
|
||||
// Equation input
|
||||
this.mathInputView = this._createMathInput();
|
||||
|
||||
// Display button
|
||||
this.displayButtonView = this._createDisplayButton();
|
||||
|
||||
// Cancel button
|
||||
this.cancelButtonView = this._createButton( t( 'Cancel' ), cancelIcon, 'ck-button-cancel', 'cancel' );
|
||||
|
||||
this.previewEnabled = previewEnabled;
|
||||
|
||||
let children = [];
|
||||
if ( this.previewEnabled ) {
|
||||
// Preview label
|
||||
this.previewLabel = new LabelView( locale );
|
||||
this.previewLabel.text = t( 'Equation preview' );
|
||||
|
||||
// Math element
|
||||
this.mathView = new MathView( engine, lazyLoad, locale, previewUid, previewClassName, katexRenderOptions );
|
||||
this.mathView.bind( 'display' ).to( this.displayButtonView, 'isOn' );
|
||||
|
||||
children = [
|
||||
this.mathInputView,
|
||||
this.displayButtonView,
|
||||
this.previewLabel,
|
||||
this.mathView
|
||||
];
|
||||
} else {
|
||||
children = [
|
||||
this.mathInputView,
|
||||
this.displayButtonView
|
||||
];
|
||||
}
|
||||
|
||||
// Add UI elements to template
|
||||
this.setTemplate( {
|
||||
tag: 'form',
|
||||
attributes: {
|
||||
class: [
|
||||
'ck',
|
||||
'ck-math-form',
|
||||
...popupClassName
|
||||
],
|
||||
tabindex: '-1',
|
||||
spellcheck: 'false'
|
||||
},
|
||||
children: [
|
||||
{
|
||||
tag: 'div',
|
||||
attributes: {
|
||||
class: [
|
||||
'ck-math-view'
|
||||
]
|
||||
},
|
||||
children
|
||||
},
|
||||
this.saveButtonView,
|
||||
this.cancelButtonView
|
||||
]
|
||||
} );
|
||||
}
|
||||
|
||||
public override render(): void {
|
||||
super.render();
|
||||
|
||||
// Prevent default form submit event & trigger custom 'submit'
|
||||
submitHandler( {
|
||||
view: this
|
||||
} );
|
||||
|
||||
// Register form elements to focusable elements
|
||||
const childViews = [
|
||||
this.mathInputView,
|
||||
this.displayButtonView,
|
||||
this.saveButtonView,
|
||||
this.cancelButtonView
|
||||
];
|
||||
|
||||
childViews.forEach( v => {
|
||||
if ( v.element ) {
|
||||
this._focusables.add( v );
|
||||
this.focusTracker.add( v.element );
|
||||
}
|
||||
} );
|
||||
|
||||
// Listen to keypresses inside form element
|
||||
if ( this.element ) {
|
||||
this.keystrokes.listenTo( this.element );
|
||||
}
|
||||
}
|
||||
|
||||
public focus(): void {
|
||||
this._focusCycler.focusFirst();
|
||||
}
|
||||
|
||||
public get equation(): string {
|
||||
return this.mathInputView.fieldView.element?.value ?? '';
|
||||
}
|
||||
|
||||
public set equation( equation: string ) {
|
||||
if ( this.mathInputView.fieldView.element ) {
|
||||
this.mathInputView.fieldView.element.value = equation;
|
||||
}
|
||||
if ( this.previewEnabled && this.mathView ) {
|
||||
this.mathView.value = equation;
|
||||
}
|
||||
}
|
||||
|
||||
public focusTracker: FocusTracker = new FocusTracker();
|
||||
public keystrokes: KeystrokeHandler = new KeystrokeHandler();
|
||||
private _focusables = new ViewCollection<FocusableView>();
|
||||
private _focusCycler: FocusCycler = new FocusCycler( {
|
||||
focusables: this._focusables,
|
||||
focusTracker: this.focusTracker,
|
||||
keystrokeHandler: this.keystrokes,
|
||||
actions: {
|
||||
focusPrevious: 'shift + tab',
|
||||
focusNext: 'tab'
|
||||
}
|
||||
} );
|
||||
|
||||
private _createMathInput() {
|
||||
const t = this.locale.t;
|
||||
|
||||
// Create equation input
|
||||
const mathInput = new MathInputView( this.locale );
|
||||
const fieldView = mathInput.fieldView;
|
||||
mathInput.infoText = t( 'Insert equation in TeX format.' );
|
||||
|
||||
const onInput = () => {
|
||||
if ( fieldView.element != null ) {
|
||||
let equationInput = fieldView.element.value.trim();
|
||||
|
||||
// If input has delimiters
|
||||
if ( hasDelimiters( equationInput ) ) {
|
||||
// Get equation without delimiters
|
||||
const params = extractDelimiters( equationInput );
|
||||
|
||||
// Remove delimiters from input field
|
||||
fieldView.element.value = params.equation;
|
||||
|
||||
equationInput = params.equation;
|
||||
|
||||
// update display button and preview
|
||||
this.displayButtonView.isOn = params.display;
|
||||
}
|
||||
if ( this.previewEnabled && this.mathView ) {
|
||||
// Update preview view
|
||||
this.mathView.value = equationInput;
|
||||
}
|
||||
|
||||
this.saveButtonView.isEnabled = !!equationInput;
|
||||
}
|
||||
};
|
||||
|
||||
fieldView.on( 'render', onInput );
|
||||
fieldView.on( 'input', onInput );
|
||||
|
||||
return mathInput;
|
||||
}
|
||||
|
||||
private _createButton(
|
||||
label: string,
|
||||
icon: string,
|
||||
className: string,
|
||||
eventName: string | null
|
||||
) {
|
||||
const button = new ButtonView( this.locale );
|
||||
|
||||
button.set( {
|
||||
label,
|
||||
icon,
|
||||
tooltip: true
|
||||
} );
|
||||
|
||||
button.extendTemplate( {
|
||||
attributes: {
|
||||
class: className
|
||||
}
|
||||
} );
|
||||
|
||||
if ( eventName ) {
|
||||
button.delegate( 'execute' ).to( this, eventName );
|
||||
}
|
||||
|
||||
return button;
|
||||
}
|
||||
|
||||
private _createDisplayButton() {
|
||||
const t = this.locale.t;
|
||||
|
||||
const switchButton = new SwitchButtonView( this.locale );
|
||||
|
||||
switchButton.set( {
|
||||
label: t( 'Display mode' ),
|
||||
withText: true
|
||||
} );
|
||||
|
||||
switchButton.extendTemplate( {
|
||||
attributes: {
|
||||
class: 'ck-button-display-toggle'
|
||||
}
|
||||
} );
|
||||
|
||||
switchButton.on( 'execute', () => {
|
||||
// Toggle state
|
||||
switchButton.isOn = !switchButton.isOn;
|
||||
|
||||
if ( this.previewEnabled && this.mathView ) {
|
||||
// Update preview view
|
||||
this.mathView.display = switchButton.isOn;
|
||||
}
|
||||
} );
|
||||
|
||||
return switchButton;
|
||||
}
|
||||
}
|
78
_regroup/ckeditor5-math/src/ui/mathview.ts
Normal file
78
_regroup/ckeditor5-math/src/ui/mathview.ts
Normal file
@ -0,0 +1,78 @@
|
||||
import { View } from 'ckeditor5/src/ui';
|
||||
import type { KatexOptions } from '../typings-external';
|
||||
import { renderEquation } from '../utils';
|
||||
import type { Locale } from 'ckeditor5/src/utils';
|
||||
|
||||
export default class MathView extends View {
|
||||
public declare value: string;
|
||||
public declare display: boolean;
|
||||
public previewUid: string;
|
||||
public previewClassName: Array<string>;
|
||||
public katexRenderOptions: KatexOptions;
|
||||
public engine:
|
||||
| 'mathjax'
|
||||
| 'katex'
|
||||
| ( ( equation: string, element: HTMLElement, display: boolean ) => void );
|
||||
public lazyLoad: undefined | ( () => Promise<void> );
|
||||
|
||||
constructor(
|
||||
engine:
|
||||
| 'mathjax'
|
||||
| 'katex'
|
||||
| ( (
|
||||
equation: string,
|
||||
element: HTMLElement,
|
||||
display: boolean,
|
||||
) => void ),
|
||||
lazyLoad: undefined | ( () => Promise<void> ),
|
||||
locale: Locale,
|
||||
previewUid: string,
|
||||
previewClassName: Array<string>,
|
||||
katexRenderOptions: KatexOptions
|
||||
) {
|
||||
super( locale );
|
||||
|
||||
this.engine = engine;
|
||||
this.lazyLoad = lazyLoad;
|
||||
this.previewUid = previewUid;
|
||||
this.katexRenderOptions = katexRenderOptions;
|
||||
this.previewClassName = previewClassName;
|
||||
|
||||
this.set( 'value', '' );
|
||||
this.set( 'display', false );
|
||||
|
||||
this.on( 'change', () => {
|
||||
if ( this.isRendered ) {
|
||||
this.updateMath();
|
||||
}
|
||||
} );
|
||||
|
||||
this.setTemplate( {
|
||||
tag: 'div',
|
||||
attributes: {
|
||||
class: [ 'ck', 'ck-math-preview' ]
|
||||
}
|
||||
} );
|
||||
}
|
||||
|
||||
public updateMath(): void {
|
||||
if ( this.element ) {
|
||||
void renderEquation(
|
||||
this.value,
|
||||
this.element,
|
||||
this.engine,
|
||||
this.lazyLoad,
|
||||
this.display,
|
||||
true,
|
||||
this.previewUid,
|
||||
this.previewClassName,
|
||||
this.katexRenderOptions
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
public override render(): void {
|
||||
super.render();
|
||||
this.updateMath();
|
||||
}
|
||||
}
|
346
_regroup/ckeditor5-math/src/utils.ts
Normal file
346
_regroup/ckeditor5-math/src/utils.ts
Normal file
@ -0,0 +1,346 @@
|
||||
import type { Editor } from 'ckeditor5/src/core';
|
||||
import type {
|
||||
Element as CKElement,
|
||||
DocumentSelection
|
||||
} from 'ckeditor5/src/engine';
|
||||
import { BalloonPanelView } from 'ckeditor5/src/ui';
|
||||
import { CKEditorError, type PositioningFunction } from 'ckeditor5/src/utils';
|
||||
import type { KatexOptions, MathJax2, MathJax3 } from './typings-external';
|
||||
|
||||
export function getSelectedMathModelWidget(
|
||||
selection: DocumentSelection
|
||||
): null | CKElement {
|
||||
const selectedElement = selection.getSelectedElement();
|
||||
|
||||
if (
|
||||
selectedElement &&
|
||||
( selectedElement.is( 'element', 'mathtex-inline' ) ||
|
||||
selectedElement.is( 'element', 'mathtex-display' ) )
|
||||
) {
|
||||
return selectedElement;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
// Simple MathJax 3 version check
|
||||
export function isMathJaxVersion3( MathJax: unknown ): MathJax is MathJax3 {
|
||||
return (
|
||||
MathJax != null && typeof MathJax == 'object' && 'version' in MathJax && typeof MathJax.version == 'string' &&
|
||||
MathJax.version.split( '.' ).length === 3 &&
|
||||
MathJax.version.split( '.' )[ 0 ] === '3'
|
||||
);
|
||||
}
|
||||
|
||||
// Simple MathJax 2 version check
|
||||
export function isMathJaxVersion2( MathJax: unknown ): MathJax is MathJax2 {
|
||||
return (
|
||||
MathJax != null && typeof MathJax == 'object' && 'Hub' in MathJax );
|
||||
}
|
||||
|
||||
// Check if equation has delimiters.
|
||||
export function hasDelimiters( text: string ): RegExpMatchArray | null {
|
||||
return text.match( /^(\\\[.*?\\\]|\\\(.*?\\\))$/ );
|
||||
}
|
||||
|
||||
// Find delimiters count
|
||||
export function delimitersCounts( text: string ): number | undefined {
|
||||
return text.match( /(\\\[|\\\]|\\\(|\\\))/g )?.length;
|
||||
}
|
||||
|
||||
// Extract delimiters and figure display mode for the model
|
||||
export function extractDelimiters( equation: string ): {
|
||||
equation: string;
|
||||
display: boolean;
|
||||
} {
|
||||
equation = equation.trim();
|
||||
|
||||
// Remove delimiters (e.g. \( \) or \[ \])
|
||||
const hasInlineDelimiters =
|
||||
equation.includes( '\\(' ) && equation.includes( '\\)' );
|
||||
const hasDisplayDelimiters =
|
||||
equation.includes( '\\[' ) && equation.includes( '\\]' );
|
||||
if ( hasInlineDelimiters || hasDisplayDelimiters ) {
|
||||
equation = equation.substring( 2, equation.length - 2 ).trim();
|
||||
}
|
||||
|
||||
return {
|
||||
equation,
|
||||
display: hasDisplayDelimiters
|
||||
};
|
||||
}
|
||||
|
||||
export async function renderEquation(
|
||||
equation: string,
|
||||
element: HTMLElement,
|
||||
engine:
|
||||
| 'katex'
|
||||
| 'mathjax'
|
||||
| undefined
|
||||
| ( (
|
||||
equation: string,
|
||||
element: HTMLElement,
|
||||
display: boolean,
|
||||
) => void ) = 'katex',
|
||||
lazyLoad?: () => Promise<void>,
|
||||
display = false,
|
||||
preview = false,
|
||||
previewUid = '',
|
||||
previewClassName: Array<string> = [],
|
||||
katexRenderOptions: KatexOptions = {}
|
||||
): Promise<void> {
|
||||
if ( engine == 'mathjax' ) {
|
||||
if ( isMathJaxVersion3( MathJax ) ) {
|
||||
selectRenderMode(
|
||||
element,
|
||||
preview,
|
||||
previewUid,
|
||||
previewClassName,
|
||||
el => {
|
||||
renderMathJax3( equation, el, display, () => {
|
||||
if ( preview ) {
|
||||
moveAndScaleElement( element, el );
|
||||
el.style.visibility = 'visible';
|
||||
}
|
||||
} );
|
||||
}
|
||||
);
|
||||
} else {
|
||||
selectRenderMode(
|
||||
element,
|
||||
preview,
|
||||
previewUid,
|
||||
previewClassName,
|
||||
el => {
|
||||
// Fixme: MathJax typesetting cause occasionally math processing error without asynchronous call
|
||||
window.setTimeout( () => {
|
||||
renderMathJax2( equation, el, display );
|
||||
|
||||
// Move and scale after rendering
|
||||
if ( preview && isMathJaxVersion2( MathJax ) ) {
|
||||
// eslint-disable-next-line new-cap
|
||||
MathJax.Hub.Queue( () => {
|
||||
moveAndScaleElement( element, el );
|
||||
el.style.visibility = 'visible';
|
||||
} );
|
||||
}
|
||||
} );
|
||||
}
|
||||
);
|
||||
}
|
||||
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
|
||||
} else if ( engine === 'katex' && window.katex !== undefined ) {
|
||||
selectRenderMode(
|
||||
element,
|
||||
preview,
|
||||
previewUid,
|
||||
previewClassName,
|
||||
el => {
|
||||
if ( katex ) {
|
||||
katex.render( equation, el, {
|
||||
throwOnError: false,
|
||||
displayMode: display,
|
||||
...katexRenderOptions
|
||||
} );
|
||||
}
|
||||
if ( preview ) {
|
||||
moveAndScaleElement( element, el );
|
||||
el.style.visibility = 'visible';
|
||||
}
|
||||
}
|
||||
);
|
||||
} else if ( typeof engine === 'function' ) {
|
||||
engine( equation, element, display );
|
||||
} else {
|
||||
if ( lazyLoad != null ) {
|
||||
try {
|
||||
window.CKEDITOR_MATH_LAZY_LOAD ??= lazyLoad();
|
||||
element.innerHTML = equation;
|
||||
await window.CKEDITOR_MATH_LAZY_LOAD;
|
||||
await renderEquation(
|
||||
equation,
|
||||
element,
|
||||
engine,
|
||||
undefined,
|
||||
display,
|
||||
preview,
|
||||
previewUid,
|
||||
previewClassName,
|
||||
katexRenderOptions
|
||||
);
|
||||
} catch ( err ) {
|
||||
element.innerHTML = equation;
|
||||
console.error(
|
||||
`math-tex-typesetting-lazy-load-failed: Lazy load failed: ${ String( err ) }`
|
||||
);
|
||||
}
|
||||
} else {
|
||||
element.innerHTML = equation;
|
||||
console.warn(
|
||||
`math-tex-typesetting-missing: Missing the mathematical typesetting engine (${ String( engine ) }) for tex.`
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export function getBalloonPositionData( editor: Editor ): {
|
||||
target: Range | HTMLElement;
|
||||
positions: Array<PositioningFunction>;
|
||||
} {
|
||||
const view = editor.editing.view;
|
||||
const defaultPositions = BalloonPanelView.defaultPositions;
|
||||
|
||||
const selectedElement = view.document.selection.getSelectedElement();
|
||||
if ( selectedElement ) {
|
||||
return {
|
||||
target: view.domConverter.viewToDom( selectedElement ),
|
||||
positions: [
|
||||
defaultPositions.southArrowNorth,
|
||||
defaultPositions.southArrowNorthWest,
|
||||
defaultPositions.southArrowNorthEast
|
||||
]
|
||||
};
|
||||
} else {
|
||||
const viewDocument = view.document;
|
||||
const firstRange = viewDocument.selection.getFirstRange();
|
||||
if ( !firstRange ) {
|
||||
/**
|
||||
* Missing first range.
|
||||
* @error math-missing-range
|
||||
*/
|
||||
throw new CKEditorError( 'math-missing-range' );
|
||||
}
|
||||
return {
|
||||
target: view.domConverter.viewRangeToDom(
|
||||
firstRange
|
||||
),
|
||||
positions: [
|
||||
defaultPositions.southArrowNorth,
|
||||
defaultPositions.southArrowNorthWest,
|
||||
defaultPositions.southArrowNorthEast
|
||||
]
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
function selectRenderMode(
|
||||
element: HTMLElement,
|
||||
preview: boolean,
|
||||
previewUid: string,
|
||||
previewClassName: Array<string>,
|
||||
cb: ( previewEl: HTMLElement ) => void
|
||||
) {
|
||||
if ( preview ) {
|
||||
createPreviewElement(
|
||||
element,
|
||||
previewUid,
|
||||
previewClassName,
|
||||
previewEl => {
|
||||
cb( previewEl );
|
||||
}
|
||||
);
|
||||
} else {
|
||||
cb( element );
|
||||
}
|
||||
}
|
||||
|
||||
function renderMathJax3( equation: string, element: HTMLElement, display: boolean, cb: () => void ) {
|
||||
let promiseFunction: undefined | ( ( input: string, options: { display: boolean } ) => Promise<HTMLElement> ) = undefined;
|
||||
if ( !isMathJaxVersion3( MathJax ) ) {
|
||||
return;
|
||||
}
|
||||
if ( MathJax.tex2chtmlPromise ) {
|
||||
promiseFunction = MathJax.tex2chtmlPromise;
|
||||
} else if ( MathJax.tex2svgPromise ) {
|
||||
promiseFunction = MathJax.tex2svgPromise;
|
||||
}
|
||||
|
||||
if ( promiseFunction != null ) {
|
||||
void promiseFunction( equation, { display } ).then( ( node: Element ) => {
|
||||
if ( element.firstChild ) {
|
||||
element.removeChild( element.firstChild );
|
||||
}
|
||||
element.appendChild( node );
|
||||
cb();
|
||||
} );
|
||||
}
|
||||
}
|
||||
|
||||
function renderMathJax2( equation: string, element: HTMLElement, display?: boolean ) {
|
||||
if ( isMathJaxVersion2( MathJax ) ) {
|
||||
if ( display ) {
|
||||
element.innerHTML = '\\[' + equation + '\\]';
|
||||
} else {
|
||||
element.innerHTML = '\\(' + equation + '\\)';
|
||||
}
|
||||
// eslint-disable-next-line
|
||||
MathJax.Hub.Queue(['Typeset', MathJax.Hub, element]);
|
||||
}
|
||||
}
|
||||
|
||||
function createPreviewElement(
|
||||
element: HTMLElement,
|
||||
previewUid: string,
|
||||
previewClassName: Array<string>,
|
||||
render: ( previewEl: HTMLElement ) => void
|
||||
): void {
|
||||
const previewEl = getPreviewElement( element, previewUid, previewClassName );
|
||||
render( previewEl );
|
||||
}
|
||||
|
||||
function getPreviewElement(
|
||||
element: HTMLElement,
|
||||
previewUid: string,
|
||||
previewClassName: Array<string>
|
||||
) {
|
||||
let previewEl = document.getElementById( previewUid );
|
||||
// Create if not found
|
||||
if ( !previewEl ) {
|
||||
previewEl = document.createElement( 'div' );
|
||||
previewEl.setAttribute( 'id', previewUid );
|
||||
previewEl.classList.add( ...previewClassName );
|
||||
previewEl.style.visibility = 'hidden';
|
||||
document.body.appendChild( previewEl );
|
||||
|
||||
let ticking = false;
|
||||
|
||||
const renderTransformation = () => {
|
||||
if ( !ticking ) {
|
||||
window.requestAnimationFrame( () => {
|
||||
if ( previewEl ) {
|
||||
moveElement( element, previewEl );
|
||||
ticking = false;
|
||||
}
|
||||
} );
|
||||
|
||||
ticking = true;
|
||||
}
|
||||
};
|
||||
|
||||
// Create scroll listener for following
|
||||
window.addEventListener( 'resize', renderTransformation );
|
||||
window.addEventListener( 'scroll', renderTransformation );
|
||||
}
|
||||
return previewEl;
|
||||
}
|
||||
|
||||
function moveAndScaleElement( parent: HTMLElement, child: HTMLElement ) {
|
||||
// Move to right place
|
||||
moveElement( parent, child );
|
||||
|
||||
// Scale parent element same as preview
|
||||
const domRect = child.getBoundingClientRect();
|
||||
parent.style.width = domRect.width + 'px';
|
||||
parent.style.height = domRect.height + 'px';
|
||||
}
|
||||
|
||||
function moveElement( parent: HTMLElement, child: HTMLElement ) {
|
||||
const domRect = parent.getBoundingClientRect();
|
||||
const left = window.scrollX + domRect.left;
|
||||
const top = window.scrollY + domRect.top;
|
||||
child.style.position = 'absolute';
|
||||
child.style.left = left + 'px';
|
||||
child.style.top = top + 'px';
|
||||
child.style.zIndex = 'var(--ck-z-panel)';
|
||||
child.style.pointerEvents = 'none';
|
||||
}
|
190
_regroup/ckeditor5-math/tests/automath.ts
Normal file
190
_regroup/ckeditor5-math/tests/automath.ts
Normal file
@ -0,0 +1,190 @@
|
||||
import Mathematics from '../src/math';
|
||||
import AutoMath from '../src/automath';
|
||||
import ClassicEditor from '@ckeditor/ckeditor5-editor-classic/src/classiceditor';
|
||||
import Clipboard from '@ckeditor/ckeditor5-clipboard/src/clipboard';
|
||||
import Paragraph from '@ckeditor/ckeditor5-paragraph/src/paragraph';
|
||||
import Undo from '@ckeditor/ckeditor5-undo/src/undo';
|
||||
import Typing from '@ckeditor/ckeditor5-typing/src/typing';
|
||||
import global from '@ckeditor/ckeditor5-utils/src/dom/global';
|
||||
import { getData, setData } from '@ckeditor/ckeditor5-engine/src/dev-utils/model';
|
||||
import { expect } from 'chai';
|
||||
import type { SinonFakeTimers } from 'sinon';
|
||||
|
||||
describe( 'AutoMath - integration', () => {
|
||||
let editorElement: HTMLDivElement, editor: ClassicEditor;
|
||||
|
||||
beforeEach( async () => {
|
||||
editorElement = document.createElement( 'div' );
|
||||
document.body.appendChild( editorElement );
|
||||
|
||||
return ClassicEditor
|
||||
.create( editorElement, {
|
||||
plugins: [ Mathematics, AutoMath, Typing, Paragraph ],
|
||||
math: {
|
||||
engine: ( equation, element, display ) => {
|
||||
if ( display ) {
|
||||
element.innerHTML = '\\[' + equation + '\\]';
|
||||
} else {
|
||||
element.innerHTML = '\\(' + equation + '\\)';
|
||||
}
|
||||
}
|
||||
}
|
||||
} )
|
||||
.then( newEditor => {
|
||||
editor = newEditor;
|
||||
} );
|
||||
} );
|
||||
|
||||
afterEach( () => {
|
||||
editorElement.remove();
|
||||
|
||||
return editor.destroy();
|
||||
} );
|
||||
|
||||
it( 'should load Clipboard plugin', () => {
|
||||
expect( editor.plugins.get( Clipboard ) ).to.instanceOf( Clipboard );
|
||||
} );
|
||||
|
||||
it( 'should load Undo plugin', () => {
|
||||
expect( editor.plugins.get( Undo ) ).to.instanceOf( Undo );
|
||||
} );
|
||||
|
||||
it( 'has proper name', () => {
|
||||
expect( AutoMath.pluginName ).to.equal( 'AutoMath' );
|
||||
} );
|
||||
|
||||
describe( 'use fake timers', () => {
|
||||
let clock: SinonFakeTimers;
|
||||
|
||||
beforeEach( () => {
|
||||
clock = sinon.useFakeTimers();
|
||||
} );
|
||||
|
||||
afterEach( () => {
|
||||
clock.restore();
|
||||
} );
|
||||
|
||||
it( 'replaces pasted text with mathtex element after 100ms', () => {
|
||||
setData( editor.model, '<paragraph>[]</paragraph>' );
|
||||
pasteHtml( editor, '\\[x^2\\]' );
|
||||
|
||||
expect( getData( editor.model ) ).to.equal(
|
||||
'<paragraph>\\[x^2\\][]</paragraph>'
|
||||
);
|
||||
|
||||
clock.tick( 100 );
|
||||
|
||||
expect( getData( editor.model ) ).to.equal(
|
||||
'<paragraph>[<mathtex display="true" equation="x^2" type="script"></mathtex>]</paragraph>'
|
||||
);
|
||||
} );
|
||||
|
||||
it( 'replaces pasted text with inline mathtex element after 100ms', () => {
|
||||
setData( editor.model, '<paragraph>[]</paragraph>' );
|
||||
pasteHtml( editor, '\\(x^2\\)' );
|
||||
|
||||
expect( getData( editor.model ) ).to.equal(
|
||||
'<paragraph>\\(x^2\\)[]</paragraph>'
|
||||
);
|
||||
|
||||
clock.tick( 100 );
|
||||
|
||||
expect( getData( editor.model ) ).to.equal(
|
||||
'<paragraph>[<mathtex display="false" equation="x^2" type="script"></mathtex>]</paragraph>'
|
||||
);
|
||||
} );
|
||||
|
||||
it( 'can undo auto-mathing', () => {
|
||||
setData( editor.model, '<paragraph>[]</paragraph>' );
|
||||
pasteHtml( editor, '\\[x^2\\]' );
|
||||
|
||||
expect( getData( editor.model ) ).to.equal(
|
||||
'<paragraph>\\[x^2\\][]</paragraph>'
|
||||
);
|
||||
|
||||
clock.tick( 100 );
|
||||
|
||||
editor.commands.execute( 'undo' );
|
||||
|
||||
expect( getData( editor.model ) ).to.equal(
|
||||
'<paragraph>\\[x^2\\][]</paragraph>'
|
||||
);
|
||||
} );
|
||||
|
||||
it( 'works for not collapsed selection inside single element', () => {
|
||||
setData( editor.model, '<paragraph>[Foo]</paragraph>' );
|
||||
pasteHtml( editor, '\\[x^2\\]' );
|
||||
|
||||
clock.tick( 100 );
|
||||
|
||||
expect( getData( editor.model ) ).to.equal(
|
||||
'<paragraph>[<mathtex display="true" equation="x^2" type="script"></mathtex>]</paragraph>'
|
||||
);
|
||||
} );
|
||||
|
||||
it( 'works for not collapsed selection over a few elements', () => {
|
||||
setData( editor.model, '<paragraph>Fo[o</paragraph><paragraph>Ba]r</paragraph>' );
|
||||
pasteHtml( editor, '\\[x^2\\]' );
|
||||
|
||||
clock.tick( 100 );
|
||||
|
||||
expect( getData( editor.model ) ).to.equal(
|
||||
'<paragraph>Fo[<mathtex display="true" equation="x^2" type="script"></mathtex>]r</paragraph>'
|
||||
);
|
||||
} );
|
||||
|
||||
it( 'inserts mathtex in-place (collapsed selection)', () => {
|
||||
setData( editor.model, '<paragraph>Foo []Bar</paragraph>' );
|
||||
pasteHtml( editor, '\\[x^2\\]' );
|
||||
|
||||
clock.tick( 100 );
|
||||
|
||||
expect( getData( editor.model ) ).to.equal(
|
||||
'<paragraph>Foo ' +
|
||||
'[<mathtex display="true" equation="x^2" type="script"></mathtex>]' +
|
||||
'Bar</paragraph>'
|
||||
);
|
||||
} );
|
||||
|
||||
it( 'inserts math in-place (non-collapsed selection)', () => {
|
||||
setData( editor.model, '<paragraph>Foo [Bar] Baz</paragraph>' );
|
||||
pasteHtml( editor, '\\[x^2\\]' );
|
||||
|
||||
clock.tick( 100 );
|
||||
|
||||
expect( getData( editor.model ) ).to.equal(
|
||||
'<paragraph>Foo ' +
|
||||
'[<mathtex display="true" equation="x^2" type="script"></mathtex>]' +
|
||||
' Baz</paragraph>'
|
||||
);
|
||||
} );
|
||||
|
||||
it( 'does nothing if pasted two equation as text', () => {
|
||||
setData( editor.model, '<paragraph>[]</paragraph>' );
|
||||
pasteHtml( editor, '\\[x^2\\] \\[\\sqrt{x}2\\]' );
|
||||
|
||||
clock.tick( 100 );
|
||||
|
||||
expect( getData( editor.model ) ).to.equal(
|
||||
'<paragraph>\\[x^2\\] \\[\\sqrt{x}2\\][]</paragraph>'
|
||||
);
|
||||
} );
|
||||
} );
|
||||
|
||||
function pasteHtml( editor: ClassicEditor, html: string ) {
|
||||
editor.editing.view.document.fire( 'paste', {
|
||||
dataTransfer: createDataTransfer( { 'text/html': html } ),
|
||||
preventDefault() {
|
||||
return undefined;
|
||||
}
|
||||
} );
|
||||
}
|
||||
|
||||
function createDataTransfer( data: Record<string, string> ) {
|
||||
return {
|
||||
getData( type: string ) {
|
||||
return data[ type ];
|
||||
}
|
||||
};
|
||||
}
|
||||
} );
|
14
_regroup/ckeditor5-math/tests/index.ts
Normal file
14
_regroup/ckeditor5-math/tests/index.ts
Normal file
@ -0,0 +1,14 @@
|
||||
import { Math as MathDll, AutoformatMath as AutoformatMathDll } from '../src';
|
||||
import Math from '../src/math';
|
||||
import AutoformatMath from '../src/autoformatmath';
|
||||
import { expect } from 'chai';
|
||||
|
||||
describe( 'CKEditor5 Math DLL', () => {
|
||||
it( 'exports Math', () => {
|
||||
expect( MathDll ).to.equal( Math );
|
||||
} );
|
||||
|
||||
it( 'exports AutoformatMath', () => {
|
||||
expect( AutoformatMathDll ).to.equal( AutoformatMath );
|
||||
} );
|
||||
} );
|
49
_regroup/ckeditor5-math/tests/lazyload.ts
Normal file
49
_regroup/ckeditor5-math/tests/lazyload.ts
Normal file
@ -0,0 +1,49 @@
|
||||
import ClassicEditor from '@ckeditor/ckeditor5-editor-classic/src/classiceditor';
|
||||
import MathUI from '../src/mathui';
|
||||
import type { EditorConfig } from '@ckeditor/ckeditor5-core/src/editor/editorconfig';
|
||||
import { expect } from 'chai';
|
||||
|
||||
describe( 'Lazy load', () => {
|
||||
let editorElement: HTMLDivElement;
|
||||
let editor: ClassicEditor;
|
||||
let lazyLoadInvoked: boolean;
|
||||
let mathUIFeature: MathUI;
|
||||
|
||||
function buildEditor( config: EditorConfig ) {
|
||||
return ClassicEditor
|
||||
.create( editorElement, {
|
||||
...config,
|
||||
plugins: [ MathUI ]
|
||||
} )
|
||||
.then( newEditor => {
|
||||
editor = newEditor;
|
||||
mathUIFeature = editor.plugins.get( MathUI );
|
||||
} );
|
||||
}
|
||||
|
||||
beforeEach( () => {
|
||||
editorElement = document.createElement( 'div' );
|
||||
document.body.appendChild( editorElement );
|
||||
|
||||
lazyLoadInvoked = false;
|
||||
} );
|
||||
|
||||
afterEach( () => {
|
||||
editorElement.remove();
|
||||
return editor.destroy();
|
||||
} );
|
||||
|
||||
it( 'initializes lazy load for KaTeX', async () => {
|
||||
await buildEditor( {
|
||||
math: {
|
||||
engine: 'katex',
|
||||
lazyLoad: async () => {
|
||||
lazyLoadInvoked = true;
|
||||
}
|
||||
}
|
||||
} );
|
||||
|
||||
mathUIFeature._showUI();
|
||||
expect( lazyLoadInvoked ).to.be.true;
|
||||
} );
|
||||
} );
|
55
_regroup/ckeditor5-math/tests/math.ts
Normal file
55
_regroup/ckeditor5-math/tests/math.ts
Normal file
@ -0,0 +1,55 @@
|
||||
import ClassicEditor from '@ckeditor/ckeditor5-editor-classic/src/classiceditor';
|
||||
import Mathematics from '../src/math';
|
||||
import MathEditing from '../src/mathediting';
|
||||
import MathUI from '../src/mathui';
|
||||
import AutoMath from '../src/automath';
|
||||
import Widget from '@ckeditor/ckeditor5-widget/src/widget';
|
||||
import global from '@ckeditor/ckeditor5-utils/src/dom/global';
|
||||
import { expect } from 'chai';
|
||||
|
||||
describe( 'Math', () => {
|
||||
let editorElement: HTMLDivElement, editor: ClassicEditor;
|
||||
|
||||
beforeEach( async () => {
|
||||
editorElement = document.createElement( 'div' );
|
||||
document.body.appendChild( editorElement );
|
||||
|
||||
return ClassicEditor
|
||||
.create( editorElement, {
|
||||
plugins: [ Mathematics ]
|
||||
} )
|
||||
.then( newEditor => {
|
||||
editor = newEditor;
|
||||
} );
|
||||
} );
|
||||
|
||||
afterEach( () => {
|
||||
editorElement.remove();
|
||||
|
||||
return editor.destroy();
|
||||
} );
|
||||
|
||||
it( 'should be loaded', () => {
|
||||
expect( editor.plugins.get( Mathematics ) ).to.instanceOf( Mathematics );
|
||||
} );
|
||||
|
||||
it( 'should load MathEditing plugin', () => {
|
||||
expect( editor.plugins.get( MathEditing ) ).to.instanceOf( MathEditing );
|
||||
} );
|
||||
|
||||
it( 'should load Widget plugin', () => {
|
||||
expect( editor.plugins.get( Widget ) ).to.instanceOf( Widget );
|
||||
} );
|
||||
|
||||
it( 'should load MathUI plugin', () => {
|
||||
expect( editor.plugins.get( MathUI ) ).to.instanceOf( MathUI );
|
||||
} );
|
||||
|
||||
it( 'should load AutoMath plugin', () => {
|
||||
expect( editor.plugins.get( AutoMath ) ).to.instanceOf( AutoMath );
|
||||
} );
|
||||
|
||||
it( 'has proper name', () => {
|
||||
expect( Mathematics.pluginName ).to.equal( 'Math' );
|
||||
} );
|
||||
} );
|
479
_regroup/ckeditor5-math/tests/mathui.ts
Normal file
479
_regroup/ckeditor5-math/tests/mathui.ts
Normal file
@ -0,0 +1,479 @@
|
||||
/* eslint-disable @typescript-eslint/no-non-null-assertion */
|
||||
/* globals document, Event */
|
||||
|
||||
import ClassicEditor from '@ckeditor/ckeditor5-editor-classic/src/classiceditor.js';
|
||||
import { keyCodes } from '@ckeditor/ckeditor5-utils/src/keyboard.js';
|
||||
import { setData as setModelData } from '@ckeditor/ckeditor5-engine/src/dev-utils/model.js';
|
||||
|
||||
import MathUI from '../src/mathui';
|
||||
import MainFormView from '../src/ui/mainformview';
|
||||
import ContextualBalloon from '@ckeditor/ckeditor5-ui/src/panel/balloon/contextualballoon.js';
|
||||
import ButtonView from '@ckeditor/ckeditor5-ui/src/button/buttonview.js';
|
||||
import View from '@ckeditor/ckeditor5-ui/src/view.js';
|
||||
import Paragraph from '@ckeditor/ckeditor5-paragraph/src/paragraph.js';
|
||||
|
||||
import ClickObserver from '@ckeditor/ckeditor5-engine/src/view/observer/clickobserver.js';
|
||||
import { expect } from 'chai';
|
||||
import type { SinonSpy } from 'sinon';
|
||||
|
||||
describe( 'MathUI', () => {
|
||||
let editorElement: HTMLDivElement;
|
||||
let editor: ClassicEditor;
|
||||
let mathUIFeature: MathUI;
|
||||
let mathButton: ButtonView;
|
||||
let balloon: ContextualBalloon;
|
||||
let formView: MainFormView | null;
|
||||
|
||||
beforeEach( async () => {
|
||||
editorElement = document.createElement( 'div' );
|
||||
document.body.appendChild( editorElement );
|
||||
|
||||
return ClassicEditor
|
||||
.create( editorElement, {
|
||||
plugins: [ MathUI, Paragraph ],
|
||||
math: {
|
||||
engine: ( equation, element, display ) => {
|
||||
if ( display ) {
|
||||
element.innerHTML = '\\[' + equation + '\\]';
|
||||
} else {
|
||||
element.innerHTML = '\\(' + equation + '\\)';
|
||||
}
|
||||
}
|
||||
}
|
||||
} )
|
||||
.then( newEditor => {
|
||||
editor = newEditor;
|
||||
mathUIFeature = editor.plugins.get( MathUI );
|
||||
mathButton = editor.ui.componentFactory.create( 'math' ) as ButtonView;
|
||||
balloon = editor.plugins.get( ContextualBalloon );
|
||||
formView = mathUIFeature.formView;
|
||||
|
||||
// There is no point to execute BalloonPanelView attachTo and pin methods so lets override it.
|
||||
sinon.stub( balloon.view, 'attachTo' ).returns( false );
|
||||
sinon.stub( balloon.view, 'pin' ).returns();
|
||||
|
||||
formView?.render();
|
||||
} );
|
||||
} );
|
||||
|
||||
afterEach( () => {
|
||||
editorElement.remove();
|
||||
|
||||
return editor.destroy();
|
||||
} );
|
||||
|
||||
describe( 'init', () => {
|
||||
it( 'should register click observer', () => {
|
||||
expect( editor.editing.view.getObserver( ClickObserver ) ).to.be.instanceOf( ClickObserver );
|
||||
} );
|
||||
|
||||
it( 'should create #formView', () => {
|
||||
expect( formView ).to.be.instanceOf( MainFormView );
|
||||
} );
|
||||
|
||||
describe( 'math toolbar button', () => {
|
||||
it( 'should be registered', () => {
|
||||
expect( mathButton ).to.be.instanceOf( ButtonView );
|
||||
} );
|
||||
|
||||
it( 'should be toggleable button', () => {
|
||||
expect( mathButton.isToggleable ).to.be.true;
|
||||
} );
|
||||
|
||||
it( 'should be bound to the math command', () => {
|
||||
const command = editor.commands.get( 'math' );
|
||||
|
||||
if ( !command ) {
|
||||
throw new Error( 'Missing math command' );
|
||||
}
|
||||
|
||||
command.isEnabled = true;
|
||||
command.value = '\\sqrt{x^2}';
|
||||
|
||||
expect( mathButton.isEnabled ).to.be.true;
|
||||
|
||||
command.isEnabled = false;
|
||||
command.value = undefined;
|
||||
|
||||
expect( mathButton.isEnabled ).to.be.false;
|
||||
} );
|
||||
|
||||
it( 'should call #_showUI upon #execute', () => {
|
||||
const spy = sinon.stub( mathUIFeature, '_showUI' ).returns( );
|
||||
|
||||
mathButton.fire( 'execute' );
|
||||
sinon.assert.calledOnce( spy );
|
||||
} );
|
||||
} );
|
||||
} );
|
||||
|
||||
describe( '_showUI()', () => {
|
||||
let balloonAddSpy: SinonSpy;
|
||||
|
||||
beforeEach( () => {
|
||||
balloonAddSpy = sinon.spy( balloon, 'add' );
|
||||
editor.editing.view.document.isFocused = true;
|
||||
} );
|
||||
|
||||
it( 'should not work if the math command is disabled', () => {
|
||||
setModelData( editor.model, '<paragraph>f[o]o</paragraph>' );
|
||||
|
||||
const command = editor.commands.get( 'math' )!;
|
||||
|
||||
command.isEnabled = false;
|
||||
|
||||
mathUIFeature._showUI();
|
||||
|
||||
expect( balloon.visibleView ).to.be.null;
|
||||
} );
|
||||
|
||||
it( 'should not throw if the UI is already visible', () => {
|
||||
setModelData( editor.model, '<paragraph>f[o]o</paragraph>' );
|
||||
|
||||
mathUIFeature._showUI();
|
||||
|
||||
expect( () => {
|
||||
mathUIFeature._showUI();
|
||||
} ).to.not.throw();
|
||||
} );
|
||||
|
||||
it( 'should add #mainFormView to the balloon and attach the balloon to the selection when text fragment is selected', () => {
|
||||
setModelData( editor.model, '<paragraph>f[o]o</paragraph>' );
|
||||
const selectedRange = editorElement.ownerDocument.getSelection()?.getRangeAt( 0 );
|
||||
|
||||
mathUIFeature._showUI();
|
||||
|
||||
expect( balloon.visibleView ).to.equal( formView );
|
||||
sinon.assert.calledWithExactly( balloonAddSpy, {
|
||||
view: formView,
|
||||
position: {
|
||||
target: selectedRange
|
||||
}
|
||||
} );
|
||||
} );
|
||||
|
||||
it( 'should add #mainFormView to the balloon and attach the balloon to the selection when selection is collapsed', () => {
|
||||
setModelData( editor.model, '<paragraph>f[]oo</paragraph>' );
|
||||
const selectedRange = editorElement.ownerDocument.getSelection()?.getRangeAt( 0 );
|
||||
|
||||
mathUIFeature._showUI();
|
||||
|
||||
expect( balloon.visibleView ).to.equal( formView );
|
||||
sinon.assert.calledWithExactly( balloonAddSpy, {
|
||||
view: formView,
|
||||
position: {
|
||||
target: selectedRange
|
||||
}
|
||||
} );
|
||||
} );
|
||||
|
||||
it( 'should disable #mainFormView element when math command is disabled', () => {
|
||||
setModelData( editor.model, '<paragraph>f[o]o</paragraph>' );
|
||||
|
||||
mathUIFeature._showUI();
|
||||
|
||||
const command = editor.commands.get( 'math' )!;
|
||||
|
||||
command.isEnabled = true;
|
||||
|
||||
expect( formView!.mathInputView.isReadOnly ).to.be.false;
|
||||
expect( formView!.saveButtonView.isEnabled ).to.be.true;
|
||||
expect( formView!.cancelButtonView.isEnabled ).to.be.true;
|
||||
|
||||
command.isEnabled = false;
|
||||
|
||||
expect( formView!.mathInputView.isReadOnly ).to.be.true;
|
||||
expect( formView!.saveButtonView.isEnabled ).to.be.false;
|
||||
expect( formView!.cancelButtonView.isEnabled ).to.be.true;
|
||||
} );
|
||||
|
||||
describe( '_hideUI()', () => {
|
||||
beforeEach( () => {
|
||||
mathUIFeature._showUI();
|
||||
} );
|
||||
|
||||
it( 'should remove the UI from the balloon', () => {
|
||||
expect( balloon.hasView( formView! ) ).to.be.true;
|
||||
|
||||
mathUIFeature._hideUI();
|
||||
|
||||
expect( balloon.hasView( formView! ) ).to.be.false;
|
||||
} );
|
||||
|
||||
it( 'should focus the `editable` by default', () => {
|
||||
const spy = sinon.spy( editor.editing.view, 'focus' );
|
||||
|
||||
mathUIFeature._hideUI();
|
||||
|
||||
// First call is from _removeFormView.
|
||||
sinon.assert.calledTwice( spy );
|
||||
} );
|
||||
|
||||
it( 'should focus the `editable` before before removing elements from the balloon', () => {
|
||||
const focusSpy = sinon.spy( editor.editing.view, 'focus' );
|
||||
const removeSpy = sinon.spy( balloon, 'remove' );
|
||||
|
||||
mathUIFeature._hideUI();
|
||||
|
||||
expect( focusSpy.calledBefore( removeSpy ) ).to.equal( true );
|
||||
} );
|
||||
|
||||
it( 'should not throw an error when views are not in the `balloon`', () => {
|
||||
mathUIFeature._hideUI();
|
||||
|
||||
expect( () => {
|
||||
mathUIFeature._hideUI();
|
||||
} ).to.not.throw();
|
||||
} );
|
||||
|
||||
it( 'should clear ui#update listener from the ViewDocument', () => {
|
||||
const spy = sinon.spy();
|
||||
|
||||
mathUIFeature.listenTo( editor.ui, 'update', spy );
|
||||
mathUIFeature._hideUI();
|
||||
editor.ui.fire( 'update' );
|
||||
|
||||
sinon.assert.notCalled( spy );
|
||||
} );
|
||||
} );
|
||||
|
||||
describe( 'keyboard support', () => {
|
||||
it( 'should show the UI on Ctrl+M keystroke', () => {
|
||||
const spy = sinon.stub( mathUIFeature, '_showUI' ).returns( );
|
||||
const command = editor.commands.get( 'math' )!;
|
||||
|
||||
command.isEnabled = false;
|
||||
|
||||
const keydata = {
|
||||
keyCode: keyCodes.m,
|
||||
ctrlKey: true,
|
||||
altKey: false,
|
||||
shiftKey: false,
|
||||
metaKey: false,
|
||||
preventDefault: sinon.spy(),
|
||||
stopPropagation: sinon.spy()
|
||||
};
|
||||
|
||||
editor.keystrokes.press( keydata );
|
||||
|
||||
sinon.assert.notCalled( spy );
|
||||
|
||||
command.isEnabled = true;
|
||||
|
||||
editor.keystrokes.press( keydata );
|
||||
sinon.assert.calledOnce( spy );
|
||||
} );
|
||||
|
||||
it( 'should prevent default action on Ctrl+M keystroke', () => {
|
||||
const preventDefaultSpy = sinon.spy();
|
||||
const stopPropagationSpy = sinon.spy();
|
||||
|
||||
const keyEvtData = {
|
||||
altKey: false,
|
||||
ctrlKey: true,
|
||||
shiftKey: false,
|
||||
metaKey: false,
|
||||
keyCode: keyCodes.m,
|
||||
preventDefault: preventDefaultSpy,
|
||||
stopPropagation: stopPropagationSpy
|
||||
};
|
||||
|
||||
editor.keystrokes.press( keyEvtData );
|
||||
|
||||
sinon.assert.calledOnce( preventDefaultSpy );
|
||||
sinon.assert.calledOnce( stopPropagationSpy );
|
||||
} );
|
||||
|
||||
it( 'should make stack with math visible on Ctrl+M keystroke - no math', () => {
|
||||
const command = editor.commands.get( 'math' )!;
|
||||
|
||||
command.isEnabled = true;
|
||||
|
||||
balloon.add( {
|
||||
view: new View(),
|
||||
stackId: 'custom'
|
||||
} );
|
||||
|
||||
const keyEvtData = {
|
||||
keyCode: keyCodes.m,
|
||||
ctrlKey: true,
|
||||
altKey: false,
|
||||
shiftKey: false,
|
||||
metaKey: false,
|
||||
preventDefault: sinon.spy(),
|
||||
stopPropagation: sinon.spy()
|
||||
};
|
||||
|
||||
editor.keystrokes.press( keyEvtData );
|
||||
|
||||
expect( balloon.visibleView ).to.equal( formView );
|
||||
} );
|
||||
|
||||
it( 'should make stack with math visible on Ctrl+M keystroke - math', () => {
|
||||
setModelData( editor.model, '<paragraph><$text equation="x^2">f[]oo</$text></paragraph>' );
|
||||
|
||||
const customView = new View();
|
||||
|
||||
balloon.add( {
|
||||
view: customView,
|
||||
stackId: 'custom'
|
||||
} );
|
||||
|
||||
expect( balloon.visibleView ).to.equal( customView );
|
||||
|
||||
editor.keystrokes.press( {
|
||||
keyCode: keyCodes.m,
|
||||
ctrlKey: true,
|
||||
altKey: false,
|
||||
shiftKey: false,
|
||||
metaKey: false,
|
||||
// @ts-expect-error - preventDefault
|
||||
preventDefault: sinon.spy(),
|
||||
stopPropagation: sinon.spy()
|
||||
} );
|
||||
|
||||
expect( balloon.visibleView ).to.equal( formView );
|
||||
} );
|
||||
|
||||
it( 'should hide the UI after Esc key press (from editor) and not focus the editable', () => {
|
||||
const spy = sinon.spy( mathUIFeature, '_hideUI' );
|
||||
const keyEvtData = {
|
||||
altKey: false,
|
||||
ctrlKey: false,
|
||||
shiftKey: false,
|
||||
metaKey: false,
|
||||
keyCode: keyCodes.esc,
|
||||
preventDefault: sinon.spy(),
|
||||
stopPropagation: sinon.spy()
|
||||
};
|
||||
|
||||
// Balloon is visible.
|
||||
mathUIFeature._showUI();
|
||||
editor.keystrokes.press( keyEvtData );
|
||||
|
||||
sinon.assert.calledWithExactly( spy );
|
||||
} );
|
||||
|
||||
it( 'should not hide the UI after Esc key press (from editor) when UI is open but is not visible', () => {
|
||||
const spy = sinon.spy( mathUIFeature, '_hideUI' );
|
||||
const keyEvtData = {
|
||||
altKey: false,
|
||||
shiftKey: false,
|
||||
ctrlKey: false,
|
||||
metaKey: false,
|
||||
keyCode: keyCodes.esc,
|
||||
preventDefault: sinon.spy(),
|
||||
stopPropagation: sinon.spy()
|
||||
};
|
||||
|
||||
const viewMock = new View();
|
||||
sinon.stub( viewMock, 'render' );
|
||||
sinon.stub( viewMock, 'destroy' );
|
||||
|
||||
mathUIFeature._showUI();
|
||||
|
||||
// Some view precedes the math UI in the balloon.
|
||||
balloon.add( { view: viewMock } );
|
||||
editor.keystrokes.press( keyEvtData );
|
||||
|
||||
sinon.assert.notCalled( spy );
|
||||
} );
|
||||
} );
|
||||
|
||||
describe( 'mouse support', () => {
|
||||
it( 'should hide the UI and not focus editable upon clicking outside the UI', () => {
|
||||
const spy = sinon.spy( mathUIFeature, '_hideUI' );
|
||||
|
||||
mathUIFeature._showUI();
|
||||
document.body.dispatchEvent( new Event( 'mousedown', { bubbles: true } ) );
|
||||
|
||||
sinon.assert.calledWithExactly( spy );
|
||||
} );
|
||||
|
||||
it( 'should not hide the UI upon clicking inside the the UI', () => {
|
||||
const spy = sinon.spy( mathUIFeature, '_hideUI' );
|
||||
|
||||
mathUIFeature._showUI();
|
||||
balloon.view.element!.dispatchEvent( new Event( 'mousedown', { bubbles: true } ) );
|
||||
|
||||
sinon.assert.notCalled( spy );
|
||||
} );
|
||||
} );
|
||||
|
||||
describe( 'math form view', () => {
|
||||
it( 'should mark the editor UI as focused when the #formView is focused', () => {
|
||||
mathUIFeature._showUI();
|
||||
expect( balloon.visibleView ).to.equal( formView );
|
||||
|
||||
editor.ui.focusTracker.isFocused = false;
|
||||
formView!.element!.dispatchEvent( new Event( 'focus' ) );
|
||||
|
||||
expect( editor.ui.focusTracker.isFocused ).to.be.true;
|
||||
} );
|
||||
|
||||
describe( 'binding', () => {
|
||||
beforeEach( () => {
|
||||
setModelData( editor.model, '<paragraph>f[o]o</paragraph>' );
|
||||
} );
|
||||
|
||||
it( 'should bind mainFormView.mathInputView#value to math command value', () => {
|
||||
const command = editor.commands.get( 'math' );
|
||||
|
||||
expect( formView!.mathInputView.value ).to.null;
|
||||
|
||||
command!.value = 'x^2';
|
||||
expect( formView!.mathInputView.value ).to.equal( 'x^2' );
|
||||
} );
|
||||
|
||||
it( 'should execute math command on mainFormView#submit event', () => {
|
||||
const executeSpy = sinon.spy( editor, 'execute' );
|
||||
|
||||
formView!.mathInputView.value = 'x^2';
|
||||
expect( formView!.mathInputView.fieldView.element!.value ).to.equal( 'x^2' );
|
||||
|
||||
formView!.mathInputView.fieldView.element!.value = 'x^2';
|
||||
formView!.fire( 'submit' );
|
||||
|
||||
expect( executeSpy.calledOnce ).to.be.true;
|
||||
expect( executeSpy.calledWith( 'math', 'x^2' ) ).to.be.true;
|
||||
} );
|
||||
|
||||
it( 'should hide the balloon on mainFormView#cancel if math command does not have a value', () => {
|
||||
mathUIFeature._showUI();
|
||||
formView!.fire( 'cancel' );
|
||||
|
||||
expect( balloon.visibleView ).to.be.null;
|
||||
} );
|
||||
|
||||
it( 'should hide the balloon after Esc key press if math command does not have a value', () => {
|
||||
const keyEvtData = {
|
||||
altKey: false,
|
||||
shiftKey: false,
|
||||
metaKey: false,
|
||||
ctrlKey: false,
|
||||
keyCode: keyCodes.esc,
|
||||
preventDefault: sinon.spy(),
|
||||
stopPropagation: sinon.spy()
|
||||
};
|
||||
|
||||
mathUIFeature._showUI();
|
||||
|
||||
formView!.keystrokes.press( keyEvtData );
|
||||
|
||||
expect( balloon.visibleView ).to.be.null;
|
||||
} );
|
||||
|
||||
it( 'should blur math input element before hiding the view', () => {
|
||||
mathUIFeature._showUI();
|
||||
|
||||
const focusSpy = sinon.spy( formView!.saveButtonView, 'focus' );
|
||||
const removeSpy = sinon.spy( balloon, 'remove' );
|
||||
|
||||
formView!.fire( 'cancel' );
|
||||
|
||||
expect( focusSpy.calledBefore( removeSpy ) ).to.equal( true );
|
||||
} );
|
||||
} );
|
||||
} );
|
||||
} );
|
||||
} );
|
9
_regroup/ckeditor5-math/tests/typings-external.ts
Normal file
9
_regroup/ckeditor5-math/tests/typings-external.ts
Normal file
@ -0,0 +1,9 @@
|
||||
import type { SinonStatic } from 'sinon';
|
||||
|
||||
declare global {
|
||||
// eslint-disable-next-line no-var
|
||||
var sinon: SinonStatic;
|
||||
}
|
||||
|
||||
export default {};
|
||||
|
1
_regroup/ckeditor5-math/theme/icons/math.svg
Normal file
1
_regroup/ckeditor5-math/theme/icons/math.svg
Normal file
@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 15.44 10.78" height="40.74" width="58.35"><path d="M8.15 0c-.06 0-.1.02-.11.03a.12.12 0 0 0-.02.01 6.81 6.81 0 0 0-2.32 4.9v.9a6.82 6.82 0 0 0 2.32 4.9.12.12 0 0 0 .02 0c.02.02.06.04.11.04.07 0 .12-.03.16-.07a.22.22 0 0 0 0-.32.12.12 0 0 0-.02-.02A4.4 4.4 0 0 1 7 8.44a7.62 7.62 0 0 1-.5-2.6v-.9c0-.82.19-1.76.5-2.6A4.4 4.4 0 0 1 8.3.42.12.12 0 0 0 8.3.39a.22.22 0 0 0 .08-.16.22.22 0 0 0-.07-.16.22.22 0 0 0-.16-.07zm4.83 0a.22.22 0 0 0-.16.07.22.22 0 0 0-.07.16c0 .08.05.13.08.16a.12.12 0 0 0 .01.02c.52.39.98 1.1 1.3 1.94.3.83.49 1.77.49 2.6v.88c0 .83-.18 1.78-.5 2.6a4.4 4.4 0 0 1-1.29 1.95.22.22 0 0 0-.01.33c.03.04.08.07.15.07.05 0 .09-.02.12-.03a.12.12 0 0 0 .02-.01 6.82 6.82 0 0 0 2.32-4.9v-.9a6.81 6.81 0 0 0-2.32-4.9.12.12 0 0 0-.02 0c-.03-.02-.06-.04-.12-.04zm-8.5.46c-.4 0-1.13.23-1.46 1.32-.06.2-.11.45-.33 1.58h-.64c-.1 0-.19-.01-.28.03a.25.25 0 0 0-.12.12.38.38 0 0 0-.03.17c0 .04 0 .1.04.14.03.04.07.07.11.08.09.03.16.02.26.02h.56l-.77 4.04c-.1.51-.19 1-.32 1.36-.06.18-.14.32-.22.4-.08.1-.16.13-.26.13-.03 0-.1 0-.2-.03.11-.05.2-.13.26-.2a.7.7 0 0 0 .13-.4.48.48 0 0 0-.16-.38.53.53 0 0 0-.35-.12c-.34 0-.7.3-.7.76 0 .27.14.5.34.64s.44.2.68.2c.33 0 .61-.17.83-.4.21-.21.37-.48.47-.69.18-.35.32-.84.43-1.25a14.17 14.17 0 0 0 .18-.8l.61-3.26h.81c.1 0 .2.01.3-.03.04-.03.09-.07.11-.13.02-.05.03-.1.03-.17 0-.05-.01-.1-.05-.14a.23.23 0 0 0-.11-.07c-.08-.03-.16-.02-.25-.02h-.73l.2-1.07a26.3 26.3 0 0 1 .24-1.07c.08-.17.22-.3.39-.3l.21.05a.7.7 0 0 0-.25.2.7.7 0 0 0-.13.4c0 .15.06.28.16.37.1.08.22.12.35.12.34 0 .7-.3.7-.76 0-.28-.15-.5-.35-.64-.2-.14-.45-.2-.7-.2zm5.4 2.78c-.6 0-1.06.37-1.36.76-.16.2-.27.4-.35.57-.07.18-.12.3-.12.42 0 .1.08.18.14.2.06.03.1.02.1.02.06 0 .12 0 .18-.04.05-.05.07-.1.08-.17v.02c.35-1.09 1-1.3 1.3-1.3.09 0 .2.01.29.09.09.07.17.2.17.5 0 .27-.18 1-.57 2.48a1.8 1.8 0 0 1-.37.75.7.7 0 0 1-.52.26c-.04 0-.13 0-.22-.03a.68.68 0 0 0 .3-.56.47.47 0 0 0-.18-.39.55.55 0 0 0-.32-.1c-.4 0-.7.33-.7.74 0 .28.16.5.38.63.21.13.48.18.73.18.39 0 .69-.2.89-.41.09-.1.15-.19.2-.27.2.36.59.68 1.16.68.6 0 1.05-.37 1.35-.76.15-.2.27-.4.34-.57.08-.18.12-.3.12-.42a.24.24 0 0 0-.11-.2c-.06-.03-.12-.02-.13-.02a.26.26 0 0 0-.18.06c-.05.05-.06.1-.07.14-.34 1.1-1.02 1.3-1.3 1.3-.17 0-.27-.06-.35-.17a.72.72 0 0 1-.11-.4c0-.22.06-.45.18-.91l.36-1.45c.03-.14.1-.44.25-.7.15-.25.36-.46.68-.46.03 0 .12 0 .22.03a.7.7 0 0 0-.32.56c0 .11.04.23.13.33.08.1.22.16.4.16.14 0 .3-.06.44-.18a.73.73 0 0 0 .24-.55c0-.32-.2-.54-.42-.66a1.52 1.52 0 0 0-.68-.16c-.34 0-.62.16-.82.34a1.8 1.8 0 0 0-.3.35 1.32 1.32 0 0 0-.5-.54 1.37 1.37 0 0 0-.63-.15z" style="line-height:1.25;-inkscape-font-specification:'Latin Modern Math'" font-weight="400" font-size="10.58" font-family="Latin Modern Math" letter-spacing="-1.06" word-spacing="0"/></svg>
|
After Width: | Height: | Size: 2.7 KiB |
35
_regroup/ckeditor5-math/theme/mathform.css
Normal file
35
_regroup/ckeditor5-math/theme/mathform.css
Normal file
@ -0,0 +1,35 @@
|
||||
.ck.ck-math-form {
|
||||
display: flex;
|
||||
align-items: flex-start;
|
||||
flex-direction: row;
|
||||
flex-wrap: nowrap;
|
||||
padding: var(--ck-spacing-standard);
|
||||
|
||||
@media screen and (max-width: 600px) {
|
||||
flex-wrap: wrap;
|
||||
|
||||
& .ck-math-view {
|
||||
flex-basis: 100%;
|
||||
|
||||
& .ck-labeled-view {
|
||||
flex-basis: 100%;
|
||||
}
|
||||
|
||||
& .ck-label {
|
||||
flex-basis: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
& .ck-button {
|
||||
flex-basis: 50%;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.ck-math-tex.ck-placeholder::before {
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
.ck.ck-toolbar-container {
|
||||
z-index: calc(var(--ck-z-panel) + 2);
|
||||
}
|
25
_regroup/ckeditor5-math/tsconfig.json
Normal file
25
_regroup/ckeditor5-math/tsconfig.json
Normal file
@ -0,0 +1,25 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"lib": [
|
||||
"DOM"
|
||||
],
|
||||
"noImplicitAny": true,
|
||||
"noImplicitOverride": true,
|
||||
"strict": true,
|
||||
"module": "es6",
|
||||
"target": "es2020",
|
||||
"sourceMap": true,
|
||||
"allowJs": true,
|
||||
"moduleResolution": "node",
|
||||
"typeRoots": [
|
||||
"typings",
|
||||
"node_modules/@types"
|
||||
]
|
||||
},
|
||||
"include": [
|
||||
"./sample",
|
||||
"./src",
|
||||
"./tests",
|
||||
"./typings"
|
||||
]
|
||||
}
|
11
_regroup/ckeditor5-math/tsconfig.release.json
Normal file
11
_regroup/ckeditor5-math/tsconfig.release.json
Normal file
@ -0,0 +1,11 @@
|
||||
{
|
||||
"extends": "./tsconfig.json",
|
||||
"compilerOptions": {
|
||||
"sourceMap": false,
|
||||
"declaration": true
|
||||
},
|
||||
"exclude": [
|
||||
"./tests/",
|
||||
"./sample/"
|
||||
]
|
||||
}
|
4
_regroup/ckeditor5-math/typings/svg.d.ts
vendored
Normal file
4
_regroup/ckeditor5-math/typings/svg.d.ts
vendored
Normal file
@ -0,0 +1,4 @@
|
||||
declare module '*.svg' {
|
||||
const src: string;
|
||||
export default src;
|
||||
}
|
8563
_regroup/ckeditor5-math/yarn.lock
Normal file
8563
_regroup/ckeditor5-math/yarn.lock
Normal file
File diff suppressed because it is too large
Load Diff
Loading…
x
Reference in New Issue
Block a user