Full Code of wangeditor-team/wangEditor for AI

master f35d8a73a0a3 cached
687 files
1.0 MB
341.8k tokens
1055 symbols
1 requests
Download .txt
Showing preview only (1,216K chars total). Download the full file or copy to clipboard to get everything.
Repository: wangeditor-team/wangEditor
Branch: master
Commit: f35d8a73a0a3
Files: 687
Total size: 1.0 MB

Directory structure:
gitextract_27463ctz/

├── .browserslistrc
├── .cz-config.js
├── .eslintignore
├── .eslintrc.js
├── .github/
│   ├── FUNDING.yml
│   ├── ISSUE_TEMPLATE/
│   │   ├── bug.md
│   │   ├── feature.md
│   │   └── question.md
│   └── workflows/
│       ├── deploy-demos.yml
│       ├── deploy-examples.yml.bak
│       ├── e2e.yml
│       ├── release.yml
│       └── test.yml
├── .gitignore
├── .npmignore
├── .prettierrc.js
├── .vscode/
│   └── settings.json
├── .yarnrc
├── CHANGELOG.md
├── LICENSE
├── README-en.md
├── README.md
├── babel.config.json
├── build/
│   ├── build-all.sh
│   ├── config/
│   │   ├── common.js
│   │   ├── dev.js
│   │   └── prd.js
│   └── create-rollup-config.js
├── commitlint.config.js
├── cypress/
│   ├── cypress.d.ts
│   ├── fixtures/
│   │   └── example.json
│   ├── integration/
│   │   └── editor.spec.ts
│   ├── plugins/
│   │   └── index.ts
│   ├── support/
│   │   ├── commands.ts
│   │   └── index.ts
│   └── tsconfig.json
├── cypress.json
├── docs/
│   ├── README.md
│   ├── dev.md
│   ├── join.md
│   ├── publish.md
│   └── test.md
├── jest.config.js
├── lerna.json
├── package.json
├── packages/
│   ├── basic-modules/
│   │   ├── CHANGELOG.md
│   │   ├── README.md
│   │   ├── __tests__/
│   │   │   ├── blockquote/
│   │   │   │   ├── blockquote-menu.test.ts
│   │   │   │   ├── elem-to-html.test.ts
│   │   │   │   ├── parse-html.test.ts
│   │   │   │   ├── plugin.test.ts
│   │   │   │   └── render-elem.test.ts
│   │   │   ├── code-block/
│   │   │   │   ├── code-block-menu.test.ts
│   │   │   │   ├── elem-to-html.test.ts
│   │   │   │   ├── parse-html.test.ts
│   │   │   │   ├── plugin.test.ts
│   │   │   │   └── render-elem.test.ts
│   │   │   ├── color/
│   │   │   │   ├── color-menus.test.ts
│   │   │   │   ├── parse-html.test.ts
│   │   │   │   ├── render-text-style.test.tsx
│   │   │   │   └── text-style-to-html.test.ts
│   │   │   ├── divider/
│   │   │   │   ├── elem-to-html.test.ts
│   │   │   │   ├── insert-divider-menu.test.ts
│   │   │   │   ├── parse-html.test.ts
│   │   │   │   ├── plugin.test.ts
│   │   │   │   └── render-elem.test.ts
│   │   │   ├── emotion/
│   │   │   │   └── emotion-menu.test.ts
│   │   │   ├── font-size-family/
│   │   │   │   ├── menu/
│   │   │   │   │   ├── font-family-menu.test.ts
│   │   │   │   │   └── font-size-menu.test.ts
│   │   │   │   ├── parse-html.test.ts
│   │   │   │   ├── render-text-style.test.tsx
│   │   │   │   └── text-style-to-html.test.ts
│   │   │   ├── full-screen/
│   │   │   │   └── full-screen-menu.test.ts
│   │   │   ├── header/
│   │   │   │   ├── elem-to-html.test.ts
│   │   │   │   ├── helper.test.ts
│   │   │   │   ├── menu/
│   │   │   │   │   ├── header-select-menu.test.ts
│   │   │   │   │   └── header1-menu.test.ts
│   │   │   │   ├── parse-html.test.ts
│   │   │   │   ├── plugin.test.ts
│   │   │   │   └── render-elem.test.ts
│   │   │   ├── image/
│   │   │   │   ├── elem-to-html.test.ts
│   │   │   │   ├── helper.test.ts
│   │   │   │   ├── menu/
│   │   │   │   │   ├── del-image.test.ts
│   │   │   │   │   ├── edit-image.test.ts
│   │   │   │   │   ├── insert-image.test.ts
│   │   │   │   │   ├── view-image-link.test.ts
│   │   │   │   │   └── width-menus.test.ts
│   │   │   │   ├── parse-html.test.ts
│   │   │   │   ├── plugin.test.ts
│   │   │   │   └── render-elem.test.ts
│   │   │   ├── indent/
│   │   │   │   ├── menu/
│   │   │   │   │   ├── decrease-indent-menu.test.ts
│   │   │   │   │   └── increase-indent-menu.test.ts
│   │   │   │   ├── parse-html.test.ts
│   │   │   │   ├── render-text-style.test.tsx
│   │   │   │   └── text-style-to-html.test.ts
│   │   │   ├── justify/
│   │   │   │   ├── menus.test.ts
│   │   │   │   ├── parse-html.test.ts
│   │   │   │   ├── render-text-style.test.tsx
│   │   │   │   └── text-style-to-html.test.ts
│   │   │   ├── line-height/
│   │   │   │   ├── line-height-menu.test.ts
│   │   │   │   ├── parse-html.test.ts
│   │   │   │   ├── render-text-style.test.tsx
│   │   │   │   └── text-style-to-html.test.ts
│   │   │   ├── link/
│   │   │   │   ├── elem-to-html.test.ts
│   │   │   │   ├── helper.test.ts
│   │   │   │   ├── menu/
│   │   │   │   │   ├── edit-link-menu.test.ts
│   │   │   │   │   ├── insert-link-menu.test.ts
│   │   │   │   │   ├── unlink-menu.test.ts
│   │   │   │   │   └── view-link-menu.test.ts
│   │   │   │   ├── parse-html.test.ts
│   │   │   │   ├── plugin.test.ts
│   │   │   │   └── render-elem.test.ts
│   │   │   ├── paragraph/
│   │   │   │   ├── elem-to-html.test.ts
│   │   │   │   ├── parse-html.test.ts
│   │   │   │   ├── plugin.test.ts
│   │   │   │   └── render-elem.test.ts
│   │   │   ├── text-style/
│   │   │   │   ├── menu/
│   │   │   │   │   ├── clear-style-menu.test.ts
│   │   │   │   │   └── menus.test.ts
│   │   │   │   ├── parse-html.test.ts
│   │   │   │   ├── parse-style-html.test.ts
│   │   │   │   ├── text-style.test.tsx
│   │   │   │   └── text-to-html.test.ts
│   │   │   ├── todo/
│   │   │   │   ├── elem-to-html.test.ts
│   │   │   │   ├── menu/
│   │   │   │   │   └── todo-menu.test.ts
│   │   │   │   ├── parse-html.test.ts
│   │   │   │   ├── plugin.test.ts
│   │   │   │   ├── pre-parse-html.test.ts
│   │   │   │   └── render-elem.test.ts
│   │   │   └── undo-redo/
│   │   │       ├── redo-menu.test.ts
│   │   │       └── undo-menu.test.ts
│   │   ├── package.json
│   │   ├── rollup.config.js
│   │   ├── src/
│   │   │   ├── assets/
│   │   │   │   ├── blockquote.less
│   │   │   │   ├── code-block.less
│   │   │   │   ├── color.less
│   │   │   │   ├── divider.less
│   │   │   │   ├── emotion.less
│   │   │   │   ├── image.less
│   │   │   │   ├── index.less
│   │   │   │   └── simple-style.less
│   │   │   ├── constants/
│   │   │   │   └── icon-svg.ts
│   │   │   ├── index.ts
│   │   │   ├── locale/
│   │   │   │   ├── en.ts
│   │   │   │   ├── index.ts
│   │   │   │   └── zh-CN.ts
│   │   │   ├── modules/
│   │   │   │   ├── blockquote/
│   │   │   │   │   ├── custom-types.ts
│   │   │   │   │   ├── elem-to-html.ts
│   │   │   │   │   ├── index.ts
│   │   │   │   │   ├── menu/
│   │   │   │   │   │   ├── BlockquoteMenu.ts
│   │   │   │   │   │   └── index.ts
│   │   │   │   │   ├── parse-elem-html.ts
│   │   │   │   │   ├── plugin.ts
│   │   │   │   │   └── render-elem.tsx
│   │   │   │   ├── code-block/
│   │   │   │   │   ├── custom-types.ts
│   │   │   │   │   ├── elem-to-html.ts
│   │   │   │   │   ├── index.ts
│   │   │   │   │   ├── menu/
│   │   │   │   │   │   ├── CodeBlockMenu.ts
│   │   │   │   │   │   └── index.ts
│   │   │   │   │   ├── parse-elem-html.ts
│   │   │   │   │   ├── plugin.ts
│   │   │   │   │   ├── pre-parse-html.ts
│   │   │   │   │   └── render-elem.tsx
│   │   │   │   ├── color/
│   │   │   │   │   ├── custom-types.ts
│   │   │   │   │   ├── index.ts
│   │   │   │   │   ├── menu/
│   │   │   │   │   │   ├── BaseMenu.ts
│   │   │   │   │   │   ├── BgColorMenu.ts
│   │   │   │   │   │   ├── ColorMenu.ts
│   │   │   │   │   │   ├── config.ts
│   │   │   │   │   │   └── index.ts
│   │   │   │   │   ├── parse-style-html.ts
│   │   │   │   │   ├── pre-parse-html.ts
│   │   │   │   │   ├── render-style.tsx
│   │   │   │   │   └── style-to-html.ts
│   │   │   │   ├── common/
│   │   │   │   │   ├── index.ts
│   │   │   │   │   └── menu/
│   │   │   │   │       ├── EnterMenu.ts
│   │   │   │   │       └── index.ts
│   │   │   │   ├── divider/
│   │   │   │   │   ├── README.md
│   │   │   │   │   ├── custom-types.ts
│   │   │   │   │   ├── elem-to-html.ts
│   │   │   │   │   ├── index.ts
│   │   │   │   │   ├── menu/
│   │   │   │   │   │   ├── DeleteDividerMenu.ts.bak
│   │   │   │   │   │   ├── InsertDividerMenu.ts
│   │   │   │   │   │   └── index.ts
│   │   │   │   │   ├── parse-elem-html.ts
│   │   │   │   │   ├── plugin.ts
│   │   │   │   │   └── render-elem.tsx
│   │   │   │   ├── emotion/
│   │   │   │   │   ├── index.ts
│   │   │   │   │   └── menu/
│   │   │   │   │       ├── EmotionMenu.ts
│   │   │   │   │       ├── config.ts
│   │   │   │   │       └── index.ts
│   │   │   │   ├── font-size-family/
│   │   │   │   │   ├── custom-types.ts
│   │   │   │   │   ├── index.ts
│   │   │   │   │   ├── menu/
│   │   │   │   │   │   ├── BaseMenu.ts
│   │   │   │   │   │   ├── FontFamilyMenu.ts
│   │   │   │   │   │   ├── FontSizeMenu.ts
│   │   │   │   │   │   ├── config.ts
│   │   │   │   │   │   └── index.ts
│   │   │   │   │   ├── parse-style-html.ts
│   │   │   │   │   ├── pre-parse-html.ts
│   │   │   │   │   ├── render-style.tsx
│   │   │   │   │   └── style-to-html.ts
│   │   │   │   ├── full-screen/
│   │   │   │   │   ├── index.ts
│   │   │   │   │   └── menu/
│   │   │   │   │       ├── FullScreen.ts
│   │   │   │   │       └── index.ts
│   │   │   │   ├── header/
│   │   │   │   │   ├── custom-types.ts
│   │   │   │   │   ├── elem-to-html.ts
│   │   │   │   │   ├── helper.ts
│   │   │   │   │   ├── index.ts
│   │   │   │   │   ├── menu/
│   │   │   │   │   │   ├── Header1ButtonMenu.ts
│   │   │   │   │   │   ├── Header2ButtonMenu.ts
│   │   │   │   │   │   ├── Header3ButtonMenu.ts
│   │   │   │   │   │   ├── Header4ButtonMenu.ts
│   │   │   │   │   │   ├── Header5ButtonMenu.ts
│   │   │   │   │   │   ├── HeaderButtonMenuBase.ts
│   │   │   │   │   │   ├── HeaderSelectMenu.ts
│   │   │   │   │   │   └── index.ts
│   │   │   │   │   ├── parse-elem-html.ts
│   │   │   │   │   ├── plugin.ts
│   │   │   │   │   └── render-elem.tsx
│   │   │   │   ├── image/
│   │   │   │   │   ├── custom-types.ts
│   │   │   │   │   ├── elem-to-html.ts
│   │   │   │   │   ├── helper.ts
│   │   │   │   │   ├── index.ts
│   │   │   │   │   ├── menu/
│   │   │   │   │   │   ├── DeleteImage.ts
│   │   │   │   │   │   ├── EditImage.ts
│   │   │   │   │   │   ├── InsertImage.ts
│   │   │   │   │   │   ├── ViewImageLink.ts
│   │   │   │   │   │   ├── Width100.ts
│   │   │   │   │   │   ├── Width30.ts
│   │   │   │   │   │   ├── Width50.ts
│   │   │   │   │   │   ├── WidthBase.ts
│   │   │   │   │   │   ├── config.ts
│   │   │   │   │   │   └── index.ts
│   │   │   │   │   ├── parse-elem-html.ts
│   │   │   │   │   ├── plugin.ts
│   │   │   │   │   └── render-elem.tsx
│   │   │   │   ├── indent/
│   │   │   │   │   ├── custom-types.ts
│   │   │   │   │   ├── index.ts
│   │   │   │   │   ├── menu/
│   │   │   │   │   │   ├── BaseMenu.ts
│   │   │   │   │   │   ├── DecreaseIndentMenu.ts
│   │   │   │   │   │   ├── IncreaseIndentMenu.ts
│   │   │   │   │   │   └── index.ts
│   │   │   │   │   ├── parse-style-html.ts
│   │   │   │   │   ├── pre-parse-html.ts
│   │   │   │   │   ├── render-style.tsx
│   │   │   │   │   └── style-to-html.ts
│   │   │   │   ├── justify/
│   │   │   │   │   ├── custom-types.ts
│   │   │   │   │   ├── index.ts
│   │   │   │   │   ├── menu/
│   │   │   │   │   │   ├── BaseMenu.ts
│   │   │   │   │   │   ├── JustifyCenterMenu.ts
│   │   │   │   │   │   ├── JustifyJustifyMenu.ts
│   │   │   │   │   │   ├── JustifyLeftMenu.ts
│   │   │   │   │   │   ├── JustifyRightMenu.ts
│   │   │   │   │   │   └── index.ts
│   │   │   │   │   ├── parse-style-html.ts
│   │   │   │   │   ├── render-style.tsx
│   │   │   │   │   └── style-to-html.ts
│   │   │   │   ├── line-height/
│   │   │   │   │   ├── custom-types.ts
│   │   │   │   │   ├── index.ts
│   │   │   │   │   ├── menu/
│   │   │   │   │   │   ├── LineHeightMenu.ts
│   │   │   │   │   │   ├── config.ts
│   │   │   │   │   │   └── index.ts
│   │   │   │   │   ├── parse-style-html.ts
│   │   │   │   │   ├── render-style.tsx
│   │   │   │   │   └── style-to-html.ts
│   │   │   │   ├── link/
│   │   │   │   │   ├── custom-types.ts
│   │   │   │   │   ├── elem-to-html.ts
│   │   │   │   │   ├── helper.ts
│   │   │   │   │   ├── index.ts
│   │   │   │   │   ├── menu/
│   │   │   │   │   │   ├── EditLink.ts
│   │   │   │   │   │   ├── InsertLink.ts
│   │   │   │   │   │   ├── UnLink.ts
│   │   │   │   │   │   ├── ViewLink.ts
│   │   │   │   │   │   ├── config.ts
│   │   │   │   │   │   └── index.ts
│   │   │   │   │   ├── parse-elem-html.ts
│   │   │   │   │   ├── plugin.ts
│   │   │   │   │   └── render-elem.tsx
│   │   │   │   ├── paragraph/
│   │   │   │   │   ├── custom-types.ts
│   │   │   │   │   ├── elem-to-html.ts
│   │   │   │   │   ├── index.ts
│   │   │   │   │   ├── parse-elem-html.ts
│   │   │   │   │   ├── plugin.ts
│   │   │   │   │   └── render-elem.tsx
│   │   │   │   ├── text-style/
│   │   │   │   │   ├── custom-types.ts
│   │   │   │   │   ├── helper.ts
│   │   │   │   │   ├── index.ts
│   │   │   │   │   ├── menu/
│   │   │   │   │   │   ├── BaseMenu.ts
│   │   │   │   │   │   ├── BoldMenu.ts
│   │   │   │   │   │   ├── ClearStyleMenu.ts
│   │   │   │   │   │   ├── CodeMenu.ts
│   │   │   │   │   │   ├── ItalicMenu.ts
│   │   │   │   │   │   ├── SubMenu.ts
│   │   │   │   │   │   ├── SupMenu.ts
│   │   │   │   │   │   ├── ThroughMenu.ts
│   │   │   │   │   │   ├── UnderlineMenu.ts
│   │   │   │   │   │   └── index.ts
│   │   │   │   │   ├── parse-style-html.ts
│   │   │   │   │   ├── render-style.tsx
│   │   │   │   │   └── style-to-html.ts
│   │   │   │   ├── todo/
│   │   │   │   │   ├── custom-types.ts
│   │   │   │   │   ├── elem-to-html.ts
│   │   │   │   │   ├── index.ts
│   │   │   │   │   ├── menu/
│   │   │   │   │   │   ├── Todo.ts
│   │   │   │   │   │   └── index.ts
│   │   │   │   │   ├── parse-elem-html.ts
│   │   │   │   │   ├── plugin.ts
│   │   │   │   │   ├── pre-parse-html.ts
│   │   │   │   │   └── render-elem.tsx
│   │   │   │   └── undo-redo/
│   │   │   │       ├── index.ts
│   │   │   │       └── menu/
│   │   │   │           ├── RedoMenu.ts
│   │   │   │           ├── UndoMenu.ts
│   │   │   │           └── index.ts
│   │   │   └── utils/
│   │   │       ├── dom.ts
│   │   │       ├── util.ts
│   │   │       └── vdom.ts
│   │   └── tsconfig.json
│   ├── code-highlight/
│   │   ├── CHANGELOG.md
│   │   ├── README.md
│   │   ├── __tests__/
│   │   │   ├── content.ts
│   │   │   ├── decorate.test.ts
│   │   │   ├── elem-to-html.test.ts
│   │   │   ├── parse-html.test.ts
│   │   │   ├── render-text-style.test.tsx
│   │   │   └── select-lang-menu.test.ts
│   │   ├── package.json
│   │   ├── rollup.config.js
│   │   ├── src/
│   │   │   ├── assets/
│   │   │   │   └── index.less
│   │   │   ├── constants/
│   │   │   │   └── svg.ts
│   │   │   ├── custom-types.ts
│   │   │   ├── decorate/
│   │   │   │   └── index.ts
│   │   │   ├── index.ts
│   │   │   ├── locale/
│   │   │   │   ├── en.ts
│   │   │   │   ├── index.ts
│   │   │   │   └── zh-CN.ts
│   │   │   ├── module/
│   │   │   │   ├── elem-to-html.ts
│   │   │   │   ├── index.ts
│   │   │   │   ├── menu/
│   │   │   │   │   ├── SelectLangMenu.ts
│   │   │   │   │   ├── config.ts
│   │   │   │   │   └── index.ts
│   │   │   │   ├── parse-style-html.ts
│   │   │   │   └── render-style.tsx
│   │   │   ├── utils/
│   │   │   │   ├── dom.ts
│   │   │   │   └── vdom.ts
│   │   │   └── vendor/
│   │   │       └── prism.ts
│   │   └── tsconfig.json
│   ├── core/
│   │   ├── CHANGELOG.md
│   │   ├── README.md
│   │   ├── __tests__/
│   │   │   ├── config/
│   │   │   │   ├── editor-config.test.ts
│   │   │   │   ├── menu-config.test.ts
│   │   │   │   └── toolbar-config.test.ts
│   │   │   ├── create/
│   │   │   │   └── content-to-html.test.ts
│   │   │   ├── create-core-editor.ts
│   │   │   ├── editor/
│   │   │   │   ├── dom-editor.test.ts
│   │   │   │   └── plugins/
│   │   │   │       ├── with-config.test.ts
│   │   │   │       ├── with-content.test.ts
│   │   │   │       ├── with-dom.test.ts
│   │   │   │       ├── with-emitter.test.ts
│   │   │   │       └── with-selection.test.ts
│   │   │   ├── i18n/
│   │   │   │   └── index.test.ts
│   │   │   ├── menus/
│   │   │   │   ├── README.md
│   │   │   │   └── register-menus/
│   │   │   │       ├── index.ts
│   │   │   │       ├── register-button-menu.ts
│   │   │   │       ├── register-modal-menu.ts
│   │   │   │       └── register-select-menu.ts
│   │   │   ├── parse-html/
│   │   │   │   └── README.md
│   │   │   ├── render/
│   │   │   │   └── README.md
│   │   │   ├── to-html/
│   │   │   │   └── README.md
│   │   │   ├── upload/
│   │   │   │   └── uploader.test.ts
│   │   │   └── utils/
│   │   │       ├── util.test.ts
│   │   │       └── vdom.test.ts
│   │   ├── package.json
│   │   ├── rollup.config.js
│   │   ├── src/
│   │   │   ├── assets/
│   │   │   │   ├── bar-item.less
│   │   │   │   ├── bar.less
│   │   │   │   ├── common.less
│   │   │   │   ├── drop-panel.less
│   │   │   │   ├── full-screen.less
│   │   │   │   ├── index.less
│   │   │   │   ├── modal.less
│   │   │   │   ├── progress.less
│   │   │   │   ├── select-list.less
│   │   │   │   └── textarea.less
│   │   │   ├── config/
│   │   │   │   ├── index.ts
│   │   │   │   ├── interface.ts
│   │   │   │   └── register.ts
│   │   │   ├── constants/
│   │   │   │   ├── index.ts
│   │   │   │   └── svg.ts
│   │   │   ├── create/
│   │   │   │   ├── bind-node-relation.ts
│   │   │   │   ├── create-editor.ts
│   │   │   │   ├── create-toolbar.ts
│   │   │   │   ├── helper.ts
│   │   │   │   └── index.ts
│   │   │   ├── editor/
│   │   │   │   ├── dom-editor.ts
│   │   │   │   ├── interface.ts
│   │   │   │   └── plugins/
│   │   │   │       ├── with-config.ts
│   │   │   │       ├── with-content.ts
│   │   │   │       ├── with-dom.ts
│   │   │   │       ├── with-emitter.ts
│   │   │   │       ├── with-event-data.ts
│   │   │   │       ├── with-max-length.ts
│   │   │   │       └── with-selection.ts
│   │   │   ├── i18n/
│   │   │   │   └── index.ts
│   │   │   ├── index.ts
│   │   │   ├── menus/
│   │   │   │   ├── README.md
│   │   │   │   ├── bar/
│   │   │   │   │   ├── HoverBar.ts
│   │   │   │   │   └── Toolbar.ts
│   │   │   │   ├── bar-item/
│   │   │   │   │   ├── BaseButton.ts
│   │   │   │   │   ├── DropPanelButton.ts
│   │   │   │   │   ├── GroupButton.ts
│   │   │   │   │   ├── ModalButton.ts
│   │   │   │   │   ├── Select.ts
│   │   │   │   │   ├── SimpleButton.ts
│   │   │   │   │   ├── index.ts
│   │   │   │   │   └── tooltip.ts
│   │   │   │   ├── helpers/
│   │   │   │   │   ├── helpers.ts
│   │   │   │   │   └── position.ts
│   │   │   │   ├── index.ts
│   │   │   │   ├── interface.ts
│   │   │   │   ├── panel-and-modal/
│   │   │   │   │   ├── BaseClass.ts
│   │   │   │   │   ├── DropPanel.ts
│   │   │   │   │   ├── Modal.ts
│   │   │   │   │   └── SelectList.ts
│   │   │   │   └── register.ts
│   │   │   ├── parse-html/
│   │   │   │   ├── README.md
│   │   │   │   ├── helper.ts
│   │   │   │   ├── index.ts
│   │   │   │   ├── parse-common-elem-html.ts
│   │   │   │   ├── parse-elem-html.ts
│   │   │   │   └── parse-text-elem-html.ts
│   │   │   ├── render/
│   │   │   │   ├── README.md
│   │   │   │   ├── element/
│   │   │   │   │   ├── getRenderElem.tsx
│   │   │   │   │   ├── renderElement.tsx
│   │   │   │   │   └── renderStyle.ts
│   │   │   │   ├── helper.ts
│   │   │   │   ├── index.ts
│   │   │   │   ├── node2Vnode.ts
│   │   │   │   └── text/
│   │   │   │       ├── genVnode.tsx
│   │   │   │       ├── renderStyle.ts
│   │   │   │       └── renderText.tsx
│   │   │   ├── text-area/
│   │   │   │   ├── TextArea.ts
│   │   │   │   ├── event-handlers/
│   │   │   │   │   ├── beforeInput.ts
│   │   │   │   │   ├── blur.ts
│   │   │   │   │   ├── click.ts
│   │   │   │   │   ├── composition.ts
│   │   │   │   │   ├── copy.ts
│   │   │   │   │   ├── cut.ts
│   │   │   │   │   ├── drag.ts
│   │   │   │   │   ├── drop.ts
│   │   │   │   │   ├── focus.ts
│   │   │   │   │   ├── index.ts
│   │   │   │   │   ├── keydown.ts
│   │   │   │   │   ├── keypress.ts
│   │   │   │   │   └── paste.ts
│   │   │   │   ├── helpers.ts
│   │   │   │   ├── place-holder.ts
│   │   │   │   ├── syncSelection.ts
│   │   │   │   └── update-view.ts
│   │   │   ├── to-html/
│   │   │   │   ├── README.md
│   │   │   │   ├── elem2html.ts
│   │   │   │   ├── index.ts
│   │   │   │   ├── node2html.ts
│   │   │   │   └── text2html.ts
│   │   │   ├── upload/
│   │   │   │   ├── createUploader.ts
│   │   │   │   ├── index.ts
│   │   │   │   └── interface.ts
│   │   │   └── utils/
│   │   │       ├── dom.ts
│   │   │       ├── hotkeys.ts
│   │   │       ├── key.ts
│   │   │       ├── line.ts
│   │   │       ├── ua.ts
│   │   │       ├── util.ts
│   │   │       ├── vdom.ts
│   │   │       └── weak-maps.ts
│   │   └── tsconfig.json
│   ├── custom-types.d.ts
│   ├── editor/
│   │   ├── CHANGELOG.md
│   │   ├── README-en.md
│   │   ├── README.md
│   │   ├── __tests__/
│   │   │   └── create.test.ts
│   │   ├── demo/
│   │   │   ├── README.md
│   │   │   ├── catalog.html
│   │   │   ├── code-highlight.html
│   │   │   ├── css/
│   │   │   │   ├── layout.css
│   │   │   │   └── view.css
│   │   │   ├── extend-menu-drop-panel.html
│   │   │   ├── extend-menu-modal.html
│   │   │   ├── extend-menu-select.html
│   │   │   ├── extend-menu.html
│   │   │   ├── get-html.html
│   │   │   ├── huge-doc.html
│   │   │   ├── index.html
│   │   │   ├── js/
│   │   │   │   ├── custom-elem.js
│   │   │   │   └── huge-content.js
│   │   │   ├── like-qq-doc.html
│   │   │   ├── max-length.html
│   │   │   ├── multi-editor.html
│   │   │   ├── set-html.html
│   │   │   └── simple-mode.html
│   │   ├── examples/
│   │   │   ├── README.md
│   │   │   ├── batch-destroy.html
│   │   │   ├── check.html
│   │   │   ├── code-highlight.html
│   │   │   ├── content-to-html.html
│   │   │   ├── css/
│   │   │   │   ├── editor.css
│   │   │   │   └── view.css
│   │   │   ├── default-mode.html
│   │   │   ├── dom7-demo.html
│   │   │   ├── headers.html
│   │   │   ├── huge-doc.html
│   │   │   ├── i18n.html
│   │   │   ├── index.html
│   │   │   ├── js/
│   │   │   │   ├── huge-content.js
│   │   │   │   └── init-content.js
│   │   │   ├── like-yuque.html
│   │   │   ├── maxlength.html
│   │   │   ├── menu.html
│   │   │   ├── modal-appendTo-body.html
│   │   │   ├── multi-editors.html
│   │   │   ├── new-menu.html
│   │   │   ├── parse-html.html
│   │   │   ├── shadow-dom.html
│   │   │   ├── simple-mode.html
│   │   │   ├── theme.html
│   │   │   ├── todo.html
│   │   │   ├── upload-image.html
│   │   │   └── upload-video.html
│   │   ├── package.json
│   │   ├── rollup.config.js
│   │   ├── src/
│   │   │   ├── Boot.ts
│   │   │   ├── assets/
│   │   │   │   └── index.less
│   │   │   ├── constants/
│   │   │   │   └── svg.ts
│   │   │   ├── create.ts
│   │   │   ├── index.ts
│   │   │   ├── init-default-config/
│   │   │   │   ├── config/
│   │   │   │   │   ├── hoverbar.ts
│   │   │   │   │   ├── index.ts
│   │   │   │   │   └── toolbar.ts
│   │   │   │   └── index.ts
│   │   │   ├── locale/
│   │   │   │   ├── en.ts
│   │   │   │   ├── index.ts
│   │   │   │   └── zh-CN.ts
│   │   │   ├── register-builtin-modules/
│   │   │   │   ├── index.ts
│   │   │   │   └── register.ts
│   │   │   └── utils/
│   │   │       ├── browser-polyfill.ts
│   │   │       ├── dom.ts
│   │   │       └── node-polyfill.ts
│   │   └── tsconfig.json
│   ├── list-module/
│   │   ├── CHANGELOG.md
│   │   ├── README.md
│   │   ├── __tests__/
│   │   │   ├── elem-to-html.test.ts
│   │   │   ├── menu/
│   │   │   │   ├── bulleted-list-menu.test.ts
│   │   │   │   └── numbered-list-menu.test.ts
│   │   │   ├── parse-html.test.ts
│   │   │   ├── plugin.test.ts
│   │   │   └── render-elem.test.ts
│   │   ├── package.json
│   │   ├── rollup.config.js
│   │   ├── src/
│   │   │   ├── assets/
│   │   │   │   └── index.less
│   │   │   ├── constants/
│   │   │   │   └── svg.ts
│   │   │   ├── index.ts
│   │   │   ├── locale/
│   │   │   │   ├── en.ts
│   │   │   │   ├── index.ts
│   │   │   │   └── zh-CN.ts
│   │   │   ├── module/
│   │   │   │   ├── custom-types.ts
│   │   │   │   ├── elem-to-html.ts
│   │   │   │   ├── index.ts
│   │   │   │   ├── menu/
│   │   │   │   │   ├── BaseMenu.ts
│   │   │   │   │   ├── BulletedListMenu.ts
│   │   │   │   │   ├── NumberedListMenu.ts
│   │   │   │   │   └── index.ts
│   │   │   │   ├── parse-elem-html.ts
│   │   │   │   ├── plugin.ts
│   │   │   │   └── render-elem.tsx
│   │   │   └── utils/
│   │   │       ├── dom.ts
│   │   │       └── maps.ts
│   │   └── tsconfig.json
│   ├── table-module/
│   │   ├── CHANGELOG.md
│   │   ├── README.md
│   │   ├── __tests__/
│   │   │   ├── elem-to-html.test.ts
│   │   │   ├── menu/
│   │   │   │   ├── delete-col.test.ts
│   │   │   │   ├── delete-row.test.ts
│   │   │   │   ├── delete-table.test.ts
│   │   │   │   ├── full-width.test.ts
│   │   │   │   ├── insert-col.test.ts
│   │   │   │   ├── insert-row.test.ts
│   │   │   │   ├── insert-table.test.ts
│   │   │   │   └── table-header.test.ts
│   │   │   ├── parse-html.test.ts
│   │   │   ├── plugin.test.ts
│   │   │   └── render-elem.test.ts
│   │   ├── package.json
│   │   ├── rollup.config.js
│   │   ├── src/
│   │   │   ├── assets/
│   │   │   │   └── index.less
│   │   │   ├── constants/
│   │   │   │   └── svg.ts
│   │   │   ├── index.ts
│   │   │   ├── locale/
│   │   │   │   ├── en.ts
│   │   │   │   ├── index.ts
│   │   │   │   └── zh-CN.ts
│   │   │   ├── module/
│   │   │   │   ├── custom-types.ts
│   │   │   │   ├── elem-to-html.ts
│   │   │   │   ├── helpers.ts
│   │   │   │   ├── index.ts
│   │   │   │   ├── menu/
│   │   │   │   │   ├── DeleteCol.ts
│   │   │   │   │   ├── DeleteRow.ts
│   │   │   │   │   ├── DeleteTable.ts
│   │   │   │   │   ├── FullWidth.ts
│   │   │   │   │   ├── InsertCol.ts
│   │   │   │   │   ├── InsertRow.ts
│   │   │   │   │   ├── InsertTable.ts
│   │   │   │   │   ├── TableHeader.ts
│   │   │   │   │   └── index.ts
│   │   │   │   ├── parse-elem-html.ts
│   │   │   │   ├── plugin.ts
│   │   │   │   ├── pre-parse-html.ts
│   │   │   │   └── render-elem/
│   │   │   │       ├── index.ts
│   │   │   │       ├── render-cell.tsx
│   │   │   │       ├── render-row.tsx
│   │   │   │       └── render-table.tsx
│   │   │   └── utils/
│   │   │       ├── dom.ts
│   │   │       └── util.ts
│   │   └── tsconfig.json
│   ├── upload-image-module/
│   │   ├── CHANGELOG.md
│   │   ├── README.md
│   │   ├── __tests__/
│   │   │   ├── config.test.ts
│   │   │   ├── plugin.test.ts
│   │   │   ├── upload-files.test.ts
│   │   │   └── upload-image-menu.test.ts
│   │   ├── package.json
│   │   ├── rollup.config.js
│   │   ├── src/
│   │   │   ├── assets/
│   │   │   │   └── index.less
│   │   │   ├── constants/
│   │   │   │   └── svg.ts
│   │   │   ├── index.ts
│   │   │   ├── locale/
│   │   │   │   ├── en.ts
│   │   │   │   ├── index.ts
│   │   │   │   └── zh-CN.ts
│   │   │   ├── module/
│   │   │   │   ├── index.ts
│   │   │   │   ├── menu/
│   │   │   │   │   ├── UploadImageMenu.ts
│   │   │   │   │   ├── config.ts
│   │   │   │   │   └── index.ts
│   │   │   │   ├── plugin.ts
│   │   │   │   └── upload-images.ts
│   │   │   └── utils/
│   │   │       └── dom.ts
│   │   └── tsconfig.json
│   ├── vars.less
│   └── video-module/
│       ├── CHANGELOG.md
│       ├── README.md
│       ├── __tests__/
│       │   ├── elem-to-html.test.ts
│       │   ├── helpler.test.ts
│       │   ├── menu/
│       │   │   ├── delete-video-menu.test.ts.bak
│       │   │   ├── insert-video-menu.test.ts
│       │   │   └── upload-video-menu.test.ts
│       │   ├── parse-html.test.ts
│       │   ├── plugin.test.ts
│       │   ├── render-elem.test.ts
│       │   └── util.test.ts
│       ├── package.json
│       ├── rollup.config.js
│       ├── src/
│       │   ├── assets/
│       │   │   └── index.less
│       │   ├── constants/
│       │   │   └── svg.ts
│       │   ├── index.ts
│       │   ├── locale/
│       │   │   ├── en.ts
│       │   │   ├── index.ts
│       │   │   └── zh-CN.ts
│       │   ├── module/
│       │   │   ├── custom-types.ts
│       │   │   ├── elem-to-html.ts
│       │   │   ├── helper/
│       │   │   │   ├── insert-video.ts
│       │   │   │   └── upload-videos.ts
│       │   │   ├── index.ts
│       │   │   ├── menu/
│       │   │   │   ├── DeleteVideoMenu.ts.bak
│       │   │   │   ├── EditVideoSizeMenu.ts
│       │   │   │   ├── InsertVideoMenu.ts
│       │   │   │   ├── UploadVideoMenu.ts
│       │   │   │   ├── config.ts
│       │   │   │   └── index.ts
│       │   │   ├── parse-elem-html.ts
│       │   │   ├── plugin.ts
│       │   │   ├── pre-parse-html.ts
│       │   │   └── render-elem.tsx
│       │   └── utils/
│       │       ├── dom.ts
│       │       └── util.ts
│       └── tsconfig.json
├── scripts/
│   └── release-tag.js
├── tests/
│   ├── setup/
│   │   └── index.ts
│   └── utils/
│       ├── create-editor.ts
│       ├── create-toolbar.ts
│       └── stylesMock.js
└── tsconfig.json

================================================
FILE CONTENTS
================================================

================================================
FILE: .browserslistrc
================================================
defaults
not IE 11
maintained node versions

================================================
FILE: .cz-config.js
================================================
module.exports = {
  types: [
    {
      value: 'WIP',
      name: '💡  WIP: Work in progress',
    },
    {
      value: 'feat',
      name: '🚀  feat: A new feature',
    },
    {
      value: 'fix',
      name: '🔧  fix: A bug fix',
    },
    {
      value: 'refactor',
      name: '🔨  refactor: A code change that neither fixes a bug nor adds a feature',
    },
    {
      value: 'release',
      name: '🛳  release: Bump to a new Semantic version',
    },
    {
      value: 'docs',
      name: '📚  docs: Documentation only changes',
    },
    {
      value: 'test',
      name: '🔍  test: Add missing tests or correcting existing tests',
    },
    {
      value: 'perf',
      name: '⚡️  perf: Changes that improve performance',
    },
    {
      value: 'chore',
      name:
        "🚬  chore: Changes that don't modify src or test files. Such as updating build tasks, package manager",
    },
    {
      value: 'workflow',
      name:
        '📦  workflow: Changes that only affect the workflow. Such as updating build systems or CI etc.',
    },
    {
      value: 'style',
      name:
        '💅  style: Code Style, Changes that do not affect the meaning of the code (white-space, formatting, missing semi-colons, etc)',
    },
    {
      value: 'revert',
      name: '⏱  revert: Revert to a commit',
    },
  ],
  // Specify the scopes for your particular project
  scopes: [],
  allowCustomScopes: true,
  allowBreakingChanges: ['feat', 'fix'],
} 


================================================
FILE: .eslintignore
================================================
node_modules/*
dist/
lib/
*.html

================================================
FILE: .eslintrc.js
================================================
module.exports = {
  env: {
    browser: true,
    es6: true,
    mocha: true,
    jest: true,
    node: true,
  },
  extends: [
    'eslint:recommended',
    'plugin:@typescript-eslint/eslint-recommended',
    'prettier/@typescript-eslint', // Uses eslint-config-prettier to disable ESLint rules from @typescript-eslint/eslint-plugin that would conflict with prettier
    'plugin:prettier/recommended', // Enables eslint-plugin-prettier and displays prettier errors as ESLint errors. Make sure this is always the last configuration in the extends array.
  ],
  globals: {
    Atomics: 'readonly',
    SharedArrayBuffer: 'readonly',
  },
  parser: '@typescript-eslint/parser',
  parserOptions: {
    ecmaVersion: 2018,
    sourceType: 'module',
  },
  plugins: ['@typescript-eslint', 'prettier'],
  rules: {
    'no-unused-vars': 0,
  },
}


================================================
FILE: .github/FUNDING.yml
================================================
# These are supported funding model platforms

github: # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2]
open_collective: wangeditor


================================================
FILE: .github/ISSUE_TEMPLATE/bug.md
================================================
---
name: 提交 bug
about: 请大家一定要按照该模板填写,以方便我们更快复现,否则该 issue 将不予受理!
---

## bug 描述

*请输入内容……*

## 你预期的样子是?

*请输入内容……*

## 系统和浏览器及版本号

- 操作系统
- 浏览器和版本

## wangEditor 版本

*请输入内容……*

## demo 能否复现该 bug ?

能/不能

- 中文 demo https://www.wangeditor.com/demo/
- English demo https://www.wangeditor.com/demo/?lang=en

## 在线 demo

*请尽量提供在线 demo (推荐以下网站),帮助我们最低成本复现 bug*

- https://codesandbox.io/
- https://codepen.io/
- https://stackblitz.com/

## 最小成本的复现步骤

(请告诉我们,如何最快的复现该 bug)

- 步骤一
- 步骤二
- 步骤三


================================================
FILE: .github/ISSUE_TEMPLATE/feature.md
================================================
---
name: 建议增加新功能
about: 请按照该模板填写,以便我们能真正了解你的需求,否则该 issue 将不予受理!
---

## 功能描述

*请输入内容……*

## 提炼几个功能点

- 功能1
- 功能2
- 功能3

## 原型图

*涉及到 UI 改动的功能,请一定提供原型图。原型图能表明功能即可,不要求规范和美观*

## 可参考的案例

*是否已有可参考的案例(如其他编辑器),有的话请给出链接*


================================================
FILE: .github/ISSUE_TEMPLATE/question.md
================================================
---
name: 使用时遇到了问题(非 bug)
about: 请按照该模板填写,以便我们能真正了解你的问题,否则该 issue 将不予受理!
---

## 问题描述

*请输入遇到的问题...*

## wangEditor 版本

*请输入内容……*

## 是否查阅了文档 ?

(文档链接 [www.wangeditor.com](https://www.wangeditor.com/) )

*是/否*

## 最小成本的复现步骤

(请告诉我们,如何**最快的**复现该问题?)

- 步骤一
- 步骤二
- 步骤三


================================================
FILE: .github/workflows/deploy-demos.yml
================================================
# This workflow will do a clean install of node dependencies, build the source code and run tests across different versions of node
# For more information see: https://help.github.com/actions/language-and-framework-guides/using-nodejs-with-github-actions
# github actions 中文文档 https://docs.github.com/cn/actions/getting-started-with-github-actions

name: deploy demos

on:
  push:
    branches: [ deploy-demos ] # 特定分支
jobs:
  deploy:
    runs-on: ubuntu-latest
    steps:
    - uses: actions/checkout@v2
    - name: set ssh key # 临时设置 ssh key
      run: |
        mkdir -p ~/.ssh/
        echo "${{secrets.SSH_KEY_FOR_GITHUB_WANGEDITOR}}" > ~/.ssh/id_rsa
        chmod 600 ~/.ssh/id_rsa
        ssh-keyscan "github.com" >> ~/.ssh/known_hosts
        echo "---------- set ssh-key ok ----------"
    - name: download and replace # 下载现有文件,替换
      run: |
        git clone git@github.com:wangEditor/demo.git
        echo "---------- git clone ok ----------"
        cp -r ./packages/editor/demo/* ./demo ## 用最新构建出来的文件,替换现有的
        echo "---------- replace ok ----------"
    - name: upload # 上传文件
      run: |
        cd ./demo
        git config user.name "github-actions"
        git config user.email "github-actions@github.com"
        echo "---------- begin git status ----------"
        echo `git status`
        echo "---------- end git status ----------"
        git add .
        git commit -m "update by github actions"
        echo "---------- begin git push ----------"
        git push origin main
        echo "---------- end git push ----------"
    - name: delete ssh key # 删除 ssh key
      run: rm -rf ~/.ssh/id_rsa




================================================
FILE: .github/workflows/deploy-examples.yml.bak
================================================
# This workflow will do a clean install of node dependencies, build the source code and run tests across different versions of node
# For more information see: https://help.github.com/actions/language-and-framework-guides/using-nodejs-with-github-actions
# github actions 中文文档 https://docs.github.com/cn/actions/getting-started-with-github-actions

name: deploy to baidu server - example page

on:
  push:
    branches:
      - 'main'
      - 'master'
      - 'dev'
      - 'feature-*'
      - 'fix-*'
      - 'hotfix-*'
      - 'refactor-*'
    paths:
      - '.github/workflows/*'
      - 'packages/**'
      - 'tests/**'
      - 'build/**'

jobs:
  deploy:
    runs-on: ubuntu-latest
    steps:
    - name: Checkout repo
      uses: actions/checkout@v2
      with:
        fetch-depth: 0
    - name: Setup node
      uses: actions/setup-node@v2
      with:
        node-version: 12.x
        registry-url: https://registry.npmjs.com
    - name: Install dependencies
      run: yarn run bootstrap
    - name: Build packages
      run: yarn build
    - name: Unit test
      run: yarn run test



    # 2022.06.07 百度云服务器到期,就不再部署到测试机了 - wangfupeng
    - name: set ssh key # 临时设置 ssh key
      run: |
        mkdir -p ~/.ssh/
        echo "${{secrets.WFP_ID_RSA}}" > ~/.ssh/id_rsa
        chmod 600 ~/.ssh/id_rsa
        ssh-keyscan ${{secrets.BAIDU_SERVER}} >> ~/.ssh/known_hosts
    - name: scp example files # 拷贝测试页面,到远程服务器
      run: |
        ## 获取当前分支名称,并创建一个同名的文件夹
        currentBranchName=`git branch | awk '$1 == "*"{print $2}'`
        mkdir -p $currentBranchName/dist/css

        ## 将 dist examples 移到刚创建的文件夹之内
        mv packages/editor/dist/css/* $currentBranchName/dist/css/
        mv packages/editor/dist/index.js $currentBranchName/dist/index.js
        mv packages/editor/dist/index.js.map $currentBranchName/dist/index.js.map
        mv packages/editor/examples/ $currentBranchName/examples/

        ## 将该文件夹,及其所有文件,上传到服务器
        echo current branch name is: $currentBranchName
        ssh work@${{secrets.BAIDU_SERVER}} "rm -rf /home/work/wangEditor-team/v5-examples/$currentBranchName"
        scp -r ./$currentBranchName work@${{secrets.BAIDU_SERVER}}:/home/work/wangEditor-team/v5-examples/$currentBranchName
    - name: delete ssh key # 删除 ssh key
      run: rm -rf ~/.ssh/id_rsa


================================================
FILE: .github/workflows/e2e.yml
================================================
# This workflow will do a clean install of node dependencies, build the source code and run tests across different versions of node
# For more information see: https://help.github.com/actions/language-and-framework-guides/using-nodejs-with-github-actions
# github actions 中文文档 https://docs.github.com/cn/actions/getting-started-with-github-actions

name: Cypress tests

on:
  push:
    branches:
      - 'master'
      - 'dev'
      - 'feature-*'
      - 'fix-*'
      - 'hotfix-*'
      - 'refactor-*'
      - 'test-*'
    paths:
      - '.github/workflows/*'
      - 'packages/**'
      - 'scripts/**'
      - 'tests/**'
      - 'build/**'
      - 'cypress/**'
      - 'babel.config.json'
      - 'cypress.json'

jobs:
  test-e2e:
    runs-on: ubuntu-latest
    container: cypress/browsers:node12.13.0-chrome78-ff70
    steps:
    - uses: actions/checkout@v2
    - name: Use Node.js ${{ matrix.node-version }}
      uses: actions/setup-node@v1
      with:
        node-version: ${{ matrix.node-version }}
    - name: Install dependencies
      run: yarn install
    - name: Build packages
      run: yarn build  
    - uses: cypress-io/github-action@v2
      with:
        browser: chrome
        start: yarn run example
        wait-on: 'http://localhost:8881/examples/default-mode.html'


================================================
FILE: .github/workflows/release.yml
================================================
name: Release

on:
  push:
    tags:
      - 'v*'

jobs:
  release:
    runs-on: ubuntu-latest
    strategy:
      max-parallel: 1

    steps:
      - name: Checkout repo
        uses: actions/checkout@v2
        with:
          fetch-depth: 0

      - name: Setup node
        uses: actions/setup-node@v2
        with:
          node-version: 14.x
          registry-url: https://registry.npmjs.com

      - name: Install dependencies
        run: yarn run bootstrap

      - name: Build packages
        run: yarn build

      - name: Unit test
        run: yarn run test 

      - name: E2E test
        uses: cypress-io/github-action@v2
        with:
          browser: chrome
          start: yarn run example
          wait-on: 'http://localhost:8881/examples/default-mode.html'   

      - name: Publish npm
        run: yarn run release:publish
        env:
          NODE_AUTH_TOKEN: ${{secrets.NPM_TOKEN}}


================================================
FILE: .github/workflows/test.yml
================================================
# This workflow will do a clean install of node dependencies, build the source code and run tests across different versions of node
# For more information see: https://help.github.com/actions/language-and-framework-guides/using-nodejs-with-github-actions
# github actions 中文文档 https://docs.github.com/cn/actions/getting-started-with-github-actions

name: Build and test

on:
  push:
    branches:
      - 'main'
      - 'master'
      - 'dev'
      - 'feature-*'
      - 'fix-*'
      - 'hotfix-*'
      - 'refactor-*'
    paths:
      - '.github/workflows/*'
      - 'packages/**'
      - 'tests/**'
      - 'build/**'

jobs:
  test:
    runs-on: ubuntu-latest
    steps:
    - name: Checkout repo
      uses: actions/checkout@v2
      with:
        fetch-depth: 0
    - name: Setup node
      uses: actions/setup-node@v2
      with:
        node-version: 14.x
        registry-url: https://registry.npmjs.com
    - name: Install dependencies
      run: yarn run bootstrap
    - name: Build packages
      run: yarn build
    - name: Unit test
      run: yarn run test

================================================
FILE: .gitignore
================================================
# Logs
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
lerna-debug.log*

# Diagnostic reports (https://nodejs.org/api/report.html)
report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json

# Runtime data
pids
*.pid
*.seed
*.pid.lock

# Directory for instrumented libs generated by jscoverage/JSCover
lib-cov

# Coverage directory used by tools like istanbul
coverage
*.lcov

# nyc test coverage
.nyc_output

# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files)
.grunt

# Bower dependency directory (https://bower.io/)
bower_components

# node-waf configuration
.lock-wscript

# Compiled binary addons (https://nodejs.org/api/addons.html)
build/Release

# Dependency directories
node_modules/
jspm_packages/

# TypeScript v1 declaration files
typings/

# TypeScript cache
*.tsbuildinfo

# Optional npm cache directory
.npm

# Optional eslint cache
.eslintcache

# Microbundle cache
.rpt2_cache/
.rts2_cache_cjs/
.rts2_cache_es/
.rts2_cache_umd/

# Optional REPL history
.node_repl_history

# Output of 'npm pack'
*.tgz

# Yarn Integrity file
.yarn-integrity

# dotenv environment variables file
.env
.env.test

# parcel-bundler cache (https://parceljs.org/)
.cache

# Next.js build output
.next

# Nuxt.js build / generate output
.nuxt
dist

# Gatsby files
.cache/
# Comment in the public line in if your project uses Gatsby and *not* Next.js
# https://nextjs.org/blog/next-9-1#public-directory-support
# public

# Serverless directories
.serverless/

# FuseBox cache
.fusebox/

# DynamoDB Local files
.dynamodb/

# TernJS port file
.tern-port

package-lock.json

.DS_Store

ISSUE.md
ISSUE1.md

.idea/

# cypress
*/cypress/videos
*/cypress/screenshots
cypress/videos
cypress/screenshots
cypress/results
cypress/logs

packages/*/dist
packages/*/dist-example

bak/

# rollup 分析包体积结果
stats.html


================================================
FILE: .npmignore
================================================
.github/
.vscode


================================================
FILE: .prettierrc.js
================================================
module.exports = {
  // 箭头函数只有一个参数的时候可以忽略括号
  arrowParens: 'avoid',
  // 括号内部不要出现空格
  bracketSpacing: true,
  // 行结束符使用 Unix 格式
  endOfLine: 'lf',
  // true: Put > on the last line instead of at a new line
  jsxBracketSameLine: false,
  // 行宽
  printWidth: 100,
  // 换行方式
  proseWrap: 'preserve',
  // 分号
  semi: false,
  // 使用单引号
  singleQuote: true,
  // 缩进
  tabWidth: 2,
  // 使用 tab 缩进
  useTabs: false,
  // 后置逗号,多行对象、数组在最后一行增加逗号
  trailingComma: 'es5',
  parser: 'typescript',
}


================================================
FILE: .vscode/settings.json
================================================
{
    "editor.formatOnSave": true,
    "cSpell.words": [
      "beforeinput",
      "bodyparser",
      "browserslist",
      "chmod",
      "clonedeep",
      "compositionend",
      "compositionstart",
      "config",
      "contenteditable",
      "elems",
      "hoverbar",
      "img",
      "isequal",
      "js",
      "keyscan",
      "luochao",
      "middlewares",
      "mkdir",
      "next",
      "nocheck",
      "prettier",
      "prettierrc",
      "prismjs",
      "snabbdom",
      "src",
      "team",
      "tecent",
      "toarray",
      "ts",
      "uppy",
      "vdom",
      "vnode",
      "wangeditor",
      "wangfupeng",
      "we",
      "write",
      "yuque"
    ],
    "typescript.tsdk": "node_modules/typescript/lib",
    "editor.codeActionsOnSave": {
        "source.fixAll.eslint": true
    },
    "eslint.validate": ["javascript"],

    "editor.detectIndentation": false,
    "editor.tabSize": 2
}

================================================
FILE: .yarnrc
================================================
registry "https://registry.npm.taobao.org"

================================================
FILE: CHANGELOG.md
================================================
# Changelog Link
- [basic-modules](./packages/basic-modules/CHANGELOG.md)
- [code-highlight](./packages/code-highlight/CHANGELOG.md)
- [core](./packages/core/CHANGELOG.md)
- [editor](./packages/editor/CHANGELOG.md)
- [list-module](./packages/list-module/CHANGELOG.md)
- [table-module](./packages/table-module/CHANGELOG.md)
- [upload-image-module](./packages/upload-image-module/CHANGELOG.md)
- [video-module](./packages/video-module/CHANGELOG.md)

================================================
FILE: LICENSE
================================================
MIT License

Copyright (c) 2021 - present wangEditor-team

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.


================================================
FILE: README-en.md
================================================
# wangEditor 5

[中文](./README.md)

## Introduction

Open source web rich text editor, run right out of the box. Support JS Vue React.

- [Document](https://www.wangeditor.com/en/)
- [Demo](https://www.wangeditor.com/demo/?lang=en)

![](./docs/images/editor-en.png)

## Communication

You can [commit an issue]((https://github.com/wangeditor-team/wangEditor/issues)) if you have any question.

## Donation

Support wangEditor open-source work https://opencollective.com/wangeditor


================================================
FILE: README.md
================================================
# wangEditor 5

[English](./README-en.md)

## 介绍

开源 Web 富文本编辑器,开箱即用,配置简单。支持 JS Vue React 。

- [文档](https://www.wangeditor.com/)
- [demo](https://www.wangeditor.com/demo/)

![](./docs/images/editor.png)

## 交流

- [讨论问题和建议](https://github.com/wangeditor-team/wangEditor/issues)

## 捐赠

支持 wangEditor 开源工作 https://opencollective.com/wangeditor


================================================
FILE: babel.config.json
================================================
{
  "presets": [
    [
      "@babel/preset-env",
      {
        "modules": false,
        "useBuiltIns": "usage",
        "corejs": 3,
        "targets": "ie 11"
      }
    ],
    "@babel/preset-typescript"
  ],
  "plugins": [
    [
      "@babel/plugin-transform-runtime",
      {
        "absoluteRuntime": false,
        "corejs": 3,
        "helpers": true,
        "regenerator": true,
        "useESModules": false
      }
    ]
  ]
}

================================================
FILE: build/build-all.sh
================================================
#!/bin/bash

## 一键打包所有 package

# 获取 yarn dev/build 类型
buildType=build
if [ -n "$1" ]; then  
  buildType=$1
fi

cd ./packages

# core 要第一个打包
cd ./core
rm -rf dist # 清空 dist 目录
yarn "$buildType"

cd ../basic-modules
rm -rf dist # 清空 dist 目录
yarn "$buildType"

# code-highlight 依赖于 basic-modules 中的 code-block
cd ../code-highlight
rm -rf dist # 清空 dist 目录
yarn "$buildType"

cd ../list-module
rm -rf dist # 清空 dist 目录
yarn "$buildType"

cd ../table-module
rm -rf dist # 清空 dist 目录
yarn "$buildType"

# upload-image 依赖于 basic-modules 中的 image
cd ../upload-image-module
rm -rf dist # 清空 dist 目录
yarn "$buildType"

cd ../video-module
rm -rf dist # 清空 dist 目录
yarn "$buildType"

# editor 依赖于上述的 core + modules
cd ../editor
rm -rf dist # 清空 dist 目录
yarn "$buildType"


================================================
FILE: build/config/common.js
================================================
/**
 * @description rollup common config
 * @author wangfupeng
 */

import path from 'path'
import commonjs from '@rollup/plugin-commonjs'
import json from '@rollup/plugin-json'
import nodeResolve from '@rollup/plugin-node-resolve'
import typescript from 'rollup-plugin-typescript2'
import replace from '@rollup/plugin-replace'
import peerDepsExternal from 'rollup-plugin-peer-deps-external'
// import del from 'rollup-plugin-delete'

export const extensions = ['.js', '.jsx', '.ts', '.tsx']
const isProd = process.env.NODE_ENV === 'production'

/**
 * 生成 common conf
 * @param {string} format 'umd' 'esm'
 * @returns common conf
 */
function genCommonConf(format) {
  return {
    input: path.resolve(__dirname, './src/index.ts'),
    output: {
      // 属性有 file format name sourcemap 等
      // https://www.rollupjs.com/guide/big-list-of-options
    },
    plugins: [
      peerDepsExternal(), // 打包结果不包含 package.json 的 peerDependencies
      json({
        compact: true,
        indent: '  ',
        preferConst: true,
      }),
      typescript({
        clean: true,
        tsconfig: path.resolve(__dirname, './tsconfig.json'),
      }),
      nodeResolve({
        browser: true, // 重要
        mainFields: format === 'esm' ? ['module', 'main'] : ['main'],
        extensions,
      }),
      commonjs(),
      replace({
        'process.env.NODE_ENV': JSON.stringify(process.env.NODE_ENV),
        preventAssignment: true,
      }),
      // del({ targets: 'dist/*' }),
    ],
  }
}

export default genCommonConf


================================================
FILE: build/config/dev.js
================================================
/**
 * @description rollup dev config
 * @author wangfupeng
 */

import postcss from 'rollup-plugin-postcss'
import autoprefixer from 'autoprefixer'
import genCommonConf from './common'

/**
 * 生成 dev config
 * @param {string} format 'umd' 'esm'
 */
function genDevConf(format) {
  const { input, output = {}, plugins = [], external } = genCommonConf(format)

  return {
    input,
    output,
    external,
    plugins: [
      ...plugins,

      postcss({
        plugins: [autoprefixer()],
        extract: 'css/style.css',
      }),
    ],
  }
}

export default genDevConf


================================================
FILE: build/config/prd.js
================================================
/**
 * @description rollup prd config
 * @author wangfupeng
 */

import babel from '@rollup/plugin-babel'
import postcss from 'rollup-plugin-postcss'
import autoprefixer from 'autoprefixer'
import cssnano from 'cssnano'
import { terser } from 'rollup-plugin-terser'
import cleanup from 'rollup-plugin-cleanup'
import genCommonConf from './common'
import { extensions } from './common'

/**
 * 生成 prd config
 * @param {string} format 'umd' 'esm'
 */
function genPrdConf(format) {
  const { input, output = {}, plugins = [], external } = genCommonConf(format)

  const finalPlugins = [
    ...plugins,
    babel({
      rootMode: 'upward',
      babelHelpers: 'runtime',
      exclude: 'node_modules/**',
      include: 'src/**',
      extensions,
    }),
    postcss({
      plugins: [
        autoprefixer(),
        cssnano(), // 压缩 css
      ],
      extract: 'css/style.css',
    }),
    cleanup({
      comments: 'none',
      extensions: ['.ts', '.tsx'],
    }),
    terser(), // 压缩 js
  ]

  return {
    input,
    output: {
      sourcemap: true,
      ...output,
    },
    external,
    plugins: finalPlugins,
  }
}

export default genPrdConf


================================================
FILE: build/create-rollup-config.js
================================================
/**
 * @description 创建 rollup 配置
 * @author wangfupeng
 */

import { merge } from 'lodash'
import { visualizer } from 'rollup-plugin-visualizer'
import genDevConf from './config/dev'
import genPrdConf from './config/prd'

// 环境变量
const ENV = process.env.NODE_ENV || 'production'
const IS_SIZE_STATS = ENV.indexOf('size_stats') >= 0 // 分析包体积
export const IS_DEV = ENV.indexOf('development') >= 0
export const IS_PRD = ENV.indexOf('production') >= 0

/**
 * 生成单个 rollup 配置
 * @param {object} customConfig { input, output, plugins ... }
 */
export function createRollupConfig(customConfig = {}) {
  const { input, output = {}, plugins = [] } = customConfig
  const { format } = output

  let baseConfig
  if (IS_PRD) {
    baseConfig = genPrdConf(format)
  } else {
    baseConfig = genDevConf(format)
  }

  if (IS_SIZE_STATS) {
    // 分析包体积。运行之后可查看 package 下的 `stats.html`
    plugins.push(visualizer())
  }

  const config = {
    input: input ? input : baseConfig.input,
    output,
    plugins,
  }

  const res = merge({}, baseConfig, config)
  return res
}


================================================
FILE: commitlint.config.js
================================================
module.exports = {
  extends: ['cz'],
  rules: {
    'type-empty': [2, 'never'],
  },
}


================================================
FILE: cypress/cypress.d.ts
================================================
/// <reference types="cypress" />

declare namespace Cypress {
  interface CustomWindow extends Window {}

  interface Chainable {
    /**
     *  Window object with additional properties used during test.
     */
    window(options?: Partial<Loggable & Timeoutable>): Chainable<CustomWindow>

    getByClass(dataTestAttribute: string, args?: any): Chainable<Element>
  }
}


================================================
FILE: cypress/fixtures/example.json
================================================
{
  "name": "Using fixtures to represent data",
  "email": "hello@cypress.io",
  "body": "Fixtures are a great way to mock data for responses to routes"
}


================================================
FILE: cypress/integration/editor.spec.ts
================================================
describe('Basic Editor', () => {
  it('create editor', () => {
    cy.visit('/examples/default-mode.html')

    cy.get('#btn-create').click()

    cy.get('#editor-toolbar').should('have.attr', 'data-w-e-toolbar', 'true')
    cy.get('#editor-text-area').should('have.attr', 'data-w-e-textarea', 'true')
    cy.get('#w-e-textarea-1').contains('一行标题')
  })
})


================================================
FILE: cypress/plugins/index.ts
================================================
/// <reference types="cypress" />
// ***********************************************************
// This example plugins/index.js can be used to load plugins
//
// You can change the location of this file or turn off loading
// the plugins file with the 'pluginsFile' configuration option.
//
// You can read more here:
// https://on.cypress.io/plugins-guide
// ***********************************************************

// This function is called when a project is opened or re-opened (e.g. due to
// the project's config changing)

/**
 * @type {Cypress.PluginConfig}
 */
export default (on: Cypress.PluginEvents, config: Cypress.PluginConfigOptions) => {
  // `on` is used to hook into various events Cypress emits
  // `config` is the resolved Cypress config
  // codeCoverageTask(on, config)
  return config
}


================================================
FILE: cypress/support/commands.ts
================================================
Cypress.Commands.add('getByClass', (selector, ...args) => {
  return cy.get(`.w-e-${selector}`, ...args)
})


================================================
FILE: cypress/support/index.ts
================================================
import './commands'


================================================
FILE: cypress/tsconfig.json
================================================
{
  "compilerOptions": {
    "target": "es5",
    "lib": ["es2015", "dom", "esnext"],
    "types": ["cypress"],
    "isolatedModules": false,
    "allowJs": true,
    "noEmit": true,
    "skipLibCheck": true,
    "esModuleInterop": true,
    "allowSyntheticDefaultImports": true,
    "strict": true,
    "forceConsistentCasingInFileNames": true,
    "module": "esnext",
    "moduleResolution": "node",
    "resolveJsonModule": true,
  },
  "include": [
    "./**/*.ts"
  ]
}


================================================
FILE: cypress.json
================================================
{
  "baseUrl": "http://localhost:8881",
  "defaultCommandTimeout": 8000,
  "video": false
}

================================================
FILE: docs/README.md
================================================
# 文档

- [开发文档](./dev.md)
- [发布到 npm](./publish.md)
- [加入研发团队](./join.md)


================================================
FILE: docs/dev.md
================================================
# 开发

## 准备工作

- 了解 slate.js
- 了解 vdom 和 snabbdom.js
- 了解 lerna
- 已安装 yarn

## 本地启动

### 打包

- 下载代码到本地,进入 `wangEditor` 目录
- 安装所有依赖 `yarn bootstrap`
- 打包所有模块 `yarn dev` 或者 `yarn build`

### 运行 demo

- 进入 `packages/editor` 目录,运行 `yarn example` ,浏览器打开 `http://localhost:8881/examples/`

## 注意事项

- 修改代码、重新打包后,要**强制刷新**浏览器
- 如果本地包依赖有问题,试试 `lerna link` 关联内部包

## 记录

全局安装一个插件 `yarn add xxx --dev -W`

注意合理使用 `peerDependencies` 和 `dependencies` ,不要重复打包一个第三方库

执行 `lerna add ...` 之后,需要重新 `lerna link` 建立内部连接

分析包体积
- 命令行,进入某个 package ,如 `cd packages/editor`
- 执行 `yarn size-stats` ,等待执行完成
- 结果会记录在 `packages/editor/stats.html` 用浏览器打开

================================================
FILE: docs/join.md
================================================
# 加入团队

欢迎加入 wangEditor 研发团队~

## V5 研发人员

- [王福朋](https://github.com/wangfupeng1988/) - wangEditor 创始人,资深前端工程师,PMP,曾就职于百度、滴滴
- [罗超](https://github.com/echoLC) - 天才就是百分之一的灵感加上百分之九十九的努力
- [TGuoW](https://github.com/TGuoW)
- [刘庆华(火热) ](https://github.com/liuqh0609) -  热爱着,年轻着
- [haha](https://github.com/hahaaha)

## 加入条件

- 熟悉 typescript ,并实际应用过
- 熟悉 webpack 或者 rollup
- 熟悉 React 或者 Vue
- 熟悉 vdom 结构,熟悉 [snabbdom.js](https://github.com/snabbdom/snabbdom) (不了解的可以先去学习一下)
- 熟悉 [slate.js](https://www.slatejs.org/) 包括:熟悉数据模型,熟悉 API,看过源码(不了解的可以先去学习一下)

## 申请加入

- 首先自我评价,符合上述加入条件
- 加入 QQ 群,私聊群主,发送一份个人简历


================================================
FILE: docs/publish.md
================================================
# 发布到 NPM

因为我们的项目是使用 `independent` 的方式组织 `muti-packgae`,所以每个包都有单独的版本号,默认使用 `lerna publish` 发布包,我们需要根据包的修改内容选择合适的版本号。**对于没有变动的 `package`,lerna 发布的时候不会算在本次发布的内容里面**。

发布的流程分两步:

第一步:将所有要发版的代码合并到 `master`  分支后,先在本地执行 `yarn release:version` 生成各个本次变动的 `package` 的版本后,自动生成 `changelog`,接着 lerna 会生成 `git tag` 并 `push` 到远程。

第二步:上面步骤完成后, `lerna` push `git tag` 到远程的时候会触发我们配置的 `git action`,走完正常的发版 `action`,具体看 [`action` 配置]('./../.github/workflows/release.yml') 。

因为目前我们还在开发当中,所以为了更加方便发版到 `npm` 进行测试,目前,项目中集成了以下 `release` 的 `script command`:

## 正常发布一个版本

```bash
yarn release:publish
```

## 发布指定的 dist-tag 版本

发布一个 `experimental` [dist-tag](https://docs.npmjs.com/cli/v7/commands/npm-dist-tag) 的版本:

```bash
yarn release:publish:experimental
```

发布一个 `next` [dist-tag](https://docs.npmjs.com/cli/v7/commands/npm-dist-tag) 的版本:

```bash
yarn release:next
```

## 发布 canary 版本

发布一个 `canary` 版本:
```bash
# 1.0.0 => 1.0.1-alpha.0+${SHA} of packages changed since the previous commit
lerna publish --canary
```



================================================
FILE: docs/test.md
================================================
# 测试
目前我们的项目已经集成了基于 `Jest` 的单元测试和基于 `Cypress` 的 `E2E` 测试,下面简单介绍两种测试运行和编写的方式。

## 单元测试
单元测试是从最底层 `API` 的角度出发,保证编辑功能的质量。虽然我们是基于 `lerna` 的 monorepo 管理方式,为了方便组织,我们的所有测试还是都放在根目录下的 `tests/units` 下,每个 `packages` 下面的包都在 `tests/units` 下对应一个目录。所以如果需要新增 `test`,可以按照这个目录组织方式决定把新的 `test` 放在哪个目录。

### 运行单元测试
目前单元测试的运行已经集成在 CI 流程中,如果本地开发后,需要自动执行单元测试,运行如下 `scripts` 命令:
```bash
yarn run test
```
查看单元测试的覆盖率:
```bash
yarn run test-c
```

### 注意事项
- **因为各个模块依赖了 `core`,如果修改了 `core` 的代码,增加了 `API`,需要运行 `yarn build` 命令,使得各个模块能读到最新的代码**。

## E2E 测试
目前我们的项目 `E2E` 测试基于 [Cypress](https://docs.cypress.io/),对于编辑器这种强依赖用户交互运作的产品,通过 `E2E` 保证编辑器交互更加稳定。

目前 `E2E` 测试只写了基本的创建基础编辑器的用例,保证打包后的代码能正常创建编辑器。

**`E2E` 测试用例目前都放在根目录下的 `cypress/integration` 目录下,如果需要增加新的测试用例,应该在此目录下创建文件。**

### 运行 E2E 测试
目前 E2E 测试的同样集成到了 CI 流程中,如果本地开发后,需要编写 E2E 测试,运行如下 `scripts` 命令:
```bash
yarn e2e:dev
```
该命令首先会启动 `packages/editor` 下面的 `example` 服务,然后再启动 Cypress 的命令, Cypress 会在本地调起 UI 界面:

![cypress](images/cypress.jpg)

然后你可以选择想要执行 E2E 的用例,然后执行后 Cypress 会调起浏览器,运行所有的测试用例,你可以直接在受控的浏览器直接调试你的测试:

![cypress-run](images/cypress-run.jpg)

如果不是为了开发新的测试用例,只是想要本地运行所有的 E2E 测试,则执行:
```bash
yarn e2e
```
Cypress 则会自己后台运行所有测试,并不会打开 UI 界面和浏览器。

================================================
FILE: jest.config.js
================================================
module.exports = {
  roots: ['<rootDir>/packages'],
  testEnvironment: 'jsdom',
  testMatch: ['**/(*.)+(spec|test).+(ts|js|tsx)'],
  transform: {
    '^.+\\.tsx?$': 'ts-jest',
    '^.+\\.js$': 'ts-jest',
  },
  globals: {
    'ts-jest': {
      tsconfig: '<rootDir>/tsconfig.json',
    },
  },
  moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'json', 'node'],
  moduleNameMapper: {
    '^.+\\.(css|less)$': '<rootDir>/tests/utils/stylesMock.js',
  },
  transformIgnorePatterns: ['node_modules/(?!(html-void-elements)/)'],
  setupFilesAfterEnv: ['<rootDir>/tests/setup/index.ts'],
  collectCoverageFrom: ['<rootDir>/packages/**/src/**/*.(ts|tsx)'],
  coveragePathIgnorePatterns: [
    'dist',
    'locale',
    'index.ts',
    'config.ts',
    'browser-polyfill.ts',
    'node-polyfill.ts',
  ],
}


================================================
FILE: lerna.json
================================================
{
  "packages": [
    "packages/*"
  ],
  "version": "independent",
  "npmClient": "yarn",
  "useWorkspaces": true,
  "command": {
    "publish": {
      "ignoreChanges": ["ignored-file", "*.md"],
      "message": "chore(release): publish",
      "conventionalCommits": true,
      "registry": "https://npm.pkg.github.com" 
    },
    "version": {
      "message": "chore(release): publish",
      "allowBranch": "master"
    }
  },
  "changelog": {
    "repo": "wangeditor-team/wangEditor",
    "labels": {
      "tag: new feature": ":rocket: New Feature",
      "tag: breaking change": ":boom: Breaking Change",
      "tag: bug fix": ":bug: Bug Fix",
      "tag: enhancement": ":nail_care: Enhancement",
      "tag: documentation": ":memo: Documentation",
      "tag: internal": ":house: Internal"
    },
    "cacheDir": ".changelog"
  },
  "changelogPreset": "angular"
}


================================================
FILE: package.json
================================================
{
  "name": "@wangeditor-team/wangeditor",
  "private": true,
  "scripts": {
    "test": "cross-env NODE_OPTIONS=--unhandled-rejections=warn jest --detectOpenHandles --passWithNoTests",
    "test-c": "cross-env NODE_OPTIONS=--unhandled-rejections=warn jest --coverage",
    "dev": "sh build/build-all.sh dev",
    "build": "sh build/build-all.sh",
    "bootstrap": "lerna bootstrap --use-workspaces",
    "release:version": "git pull origin master && lerna version --conventional-commits && node ./scripts/release-tag.js",
    "release:publish:experimental": "lerna publish --dist-tag experimental",
    "release:publish:canary": "lerna publish --canary",
    "release:next": "yarn prerelease && lerna publish --dist-tag next",
    "release:publish": "lerna publish from-git --yes",
    "release:package": "lerna publish from-package --yes",
    "prerelease": "yarn build",
    "format": "yarn prettier --write",
    "lint": "eslint \"packages/*/+(src|__tests__)/**/*.+(ts|tsx)\"",
    "prettier": "prettier --ignore-path .gitignore \"packages/*/+(src|__tests__)/**/*.+(ts|tsx)\"",
    "cypress:open": "cypress open",
    "cypress:run": "cypress run",
    "e2e:dev": "concurrently \"yarn example\" \"yarn run cypress:open\"",
    "e2e": "concurrently \"yarn example\" \"yarn run cypress:run\"",
    "example": "lerna exec --scope @wangeditor/editor -- yarn run example"
  },
  "workspaces": [
    "packages/*"
  ],
  "lint-staged": {
    "packages/**/*.{ts,tsx}": [
      "yarn lint",
      "yarn format",
      "git add ."
    ]
  },
  "husky": {
    "hooks": {
      "pre-commit": "lint-staged",
      "commit-msg": "commitlint -E HUSKY_GIT_PARAMS"
    }
  },
  "config": {
    "commitizen": {
      "path": "node_modules/cz-customizable"
    }
  },
  "devDependencies": {
    "@babel/core": "^7.14.6",
    "@babel/plugin-proposal-class-properties": "^7.10.4",
    "@babel/plugin-proposal-object-rest-spread": "^7.11.0",
    "@babel/plugin-transform-runtime": "^7.14.5",
    "@babel/preset-env": "^7.14.5",
    "@babel/preset-typescript": "^7.14.5",
    "@babel/runtime-corejs3": "^7.14.7",
    "@rollup/plugin-babel": "^5.3.0",
    "@rollup/plugin-commonjs": "^17.1.0",
    "@rollup/plugin-json": "^4.1.0",
    "@rollup/plugin-node-resolve": "^11.2.0",
    "@rollup/plugin-replace": "^2.4.2",
    "@testing-library/jest-dom": "^5.14.1",
    "@types/jest": "^25.2.1",
    "@typescript-eslint/eslint-plugin": "^2.31.0",
    "@typescript-eslint/parser": "^4.4.1",
    "autoprefixer": "^10.2.5",
    "babel-core": "^7.0.0-bridge.0",
    "babel-jest": "^27.0.6",
    "babel-plugin-istanbul": "^6.0.0",
    "commitlint": "^11.0.0",
    "commitlint-config-cz": "^0.13.2",
    "concurrently": "^6.2.0",
    "conventional-changelog": "^3.1.24",
    "cross-env": "^7.0.2",
    "cssnano": "^5.0.3",
    "cypress": "^8.6.0",
    "cz-customizable": "^6.3.0",
    "eslint": "^7.21.0",
    "eslint-config-prettier": "^6.11.0",
    "eslint-plugin-prettier": "^3.1.3",
    "http-server": "^0.12.3",
    "husky": "^4.2.5",
    "jest": "^27.0.6",
    "lerna": "^3.20.2",
    "lerna-changelog": "^1.0.1",
    "less": "^3.11.1",
    "lint-staged": "^10.2.2",
    "lodash": "^4.17.21",
    "nock": "^13.2.4",
    "nodemon": "^2.0.6",
    "postcss": "^8.2.15",
    "prettier": "^2.0.5",
    "release-it": "^14.2.0",
    "rollup": "^2.41.0",
    "rollup-plugin-cleanup": "^3.2.1",
    "rollup-plugin-copy": "^3.4.0",
    "rollup-plugin-delete": "^2.0.0",
    "rollup-plugin-generate-html-template": "^1.7.0",
    "rollup-plugin-peer-deps-external": "^2.2.4",
    "rollup-plugin-postcss": "^4.0.0",
    "rollup-plugin-serve": "^1.1.0",
    "rollup-plugin-terser": "^7.0.2",
    "rollup-plugin-typescript2": "^0.30.0",
    "rollup-plugin-visualizer": "^5.5.0",
    "ts-jest": "^27.0.4",
    "tslib": "^2.3.0",
    "typescript": "4.3.2"
  },
  "dependencies": {
    "@babel/runtime": "^7.14.6"
  }
}


================================================
FILE: packages/basic-modules/CHANGELOG.md
================================================
# Change Log

All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.

## [1.1.7](https://github.com/wangeditor-team/wangEditor/compare/@wangeditor/basic-modules@1.1.6...@wangeditor/basic-modules@1.1.7) (2022-11-14)


### Bug Fixes

* **font family menu:** 处理 setHtml 的时候字体样式回显失败的问题 ([b941bab](https://github.com/wangeditor-team/wangEditor/commit/b941babbdc6bd5bf7da0cce826803a8fde011e07))





## [1.1.6](https://github.com/wangeditor-team/wangEditor/compare/@wangeditor/basic-modules@1.1.5...@wangeditor/basic-modules@1.1.6) (2022-09-27)

**Note:** Version bump only for package @wangeditor/basic-modules





## [1.1.5](https://github.com/wangeditor-team/wangEditor/compare/@wangeditor/basic-modules@1.1.4...@wangeditor/basic-modules@1.1.5) (2022-09-15)


### Bug Fixes

* 图片 100% 有横向滚动条 ([d21322a](https://github.com/wangeditor-team/wangEditor/commit/d21322a1a9f2e3172a1bd5e175f5ebbb5f2ed074))
* 插入表格会删掉去掉 issue 4711 ([d4fac4e](https://github.com/wangeditor-team/wangEditor/commit/d4fac4efd06480457a95c2b06e7472cf6204de58))





## [1.1.4](https://github.com/wangeditor-team/wangEditor/compare/@wangeditor/basic-modules@1.1.3...@wangeditor/basic-modules@1.1.4) (2022-09-14)


### Bug Fixes

* font-size - 支持配置 name value ([206ebd9](https://github.com/wangeditor-team/wangEditor/commit/206ebd994d2635704d93ef9ebe0022d7d72ddea8))





## [1.1.3](https://github.com/wangeditor-team/wangEditor/compare/@wangeditor/basic-modules@1.1.2...@wangeditor/basic-modules@1.1.3) (2022-07-13)


### Bug Fixes

* parse indent style 负数 ([c8d746e](https://github.com/wangeditor-team/wangEditor/commit/c8d746e0464bdda626313c17af4d015681ccc3e8))
* 兼容 word 文字背景色 ([e820b26](https://github.com/wangeditor-team/wangEditor/commit/e820b26730d34480994a343ab262c043c30a4495))





## [1.1.2](https://github.com/wangeditor-team/wangEditor/compare/@wangeditor/basic-modules@1.1.1...@wangeditor/basic-modules@1.1.2) (2022-07-11)


### Bug Fixes

* editor.focus() 参数语法错误 ([334fa21](https://github.com/wangeditor-team/wangEditor/commit/334fa217d43fdaa95454e7c85a53526b7b777fda))
* 修复html回显时,部分字体回显问题 ([c83ffa7](https://github.com/wangeditor-team/wangEditor/commit/c83ffa70da655d03bfd639f2d1fd04986440ead2))





## [1.1.1](https://github.com/wangeditor-team/wangEditor/compare/@wangeditor/basic-modules@1.1.0...@wangeditor/basic-modules@1.1.1) (2022-06-02)


### Bug Fixes

* issue 4308 - 自定义字号、字体无法回显 ([ad38b8c](https://github.com/wangeditor-team/wangEditor/commit/ad38b8ce6dbcff1d65785c8d6701238ad351f562))
* 修复在空字符上插入 link 报错的问题 ([e838f06](https://github.com/wangeditor-team/wangEditor/commit/e838f069f556a5d3206e48a5ed76f8d1e0ae3d05))





# [1.1.0](https://github.com/wangeditor-team/wangEditor/compare/@wangeditor/basic-modules@1.0.1...@wangeditor/basic-modules@1.1.0) (2022-05-25)


### Bug Fixes

* 粘贴 HTML 后 font-size font-family line-height 不显示 ([2281957](https://github.com/wangeditor-team/wangEditor/commit/2281957020a30de9cda1c5e9d5e20c6668b7f592))


### Features

* enter menu ([988fc31](https://github.com/wangeditor-team/wangEditor/commit/988fc31f31de3d37dffbf54abb784cceb8e6118d))





## 1.0.1 (2022-04-18)


### Bug Fixes

* 部分菜单 disabled ([87f1233](https://github.com/wangeditor-team/wangEditor/commit/87f12332a087072406c1988dc5cef2eae8335375))
* 插入图片的 < > 替换 ([5721560](https://github.com/wangeditor-team/wangEditor/commit/57215609ada8b9d15f5505d1ba52e49707b5b183))
* 错别字 alwaysEnable ([82c5136](https://github.com/wangeditor-team/wangEditor/commit/82c5136f8496be420dfa26b0f30522e19924a907))
* 分割线后无法输入内容 ([146fd05](https://github.com/wangeditor-team/wangEditor/commit/146fd05108592d50d036d0f37a2e29fcdd2a97be))
* 更新各包之间依赖版本 ([75c552c](https://github.com/wangeditor-team/wangEditor/commit/75c552cc8ed54765bebb86a7ec5329a7fc79e85f))
* 更新了 basic-module 依赖版本 ([20c9543](https://github.com/wangeditor-team/wangEditor/commit/20c9543dc9249af6fc7e3a9895ed7f64709ca6ee))
* 禁用时 image 的样式 ([42c993a](https://github.com/wangeditor-team/wangEditor/commit/42c993a7668d90ce049b88a01df21b28912c679f))
* 全选设置字体报错 ([cdb14d1](https://github.com/wangeditor-team/wangEditor/commit/cdb14d10330b5736534e7aaf3a070df2804a8be2))
* 上下标文案显示 ([0e97da1](https://github.com/wangeditor-team/wangEditor/commit/0e97da18279cee6ea06c217972fee4faf9e4758f))
* 添加链接,空格也会在链接中的问题 ([c656827](https://github.com/wangeditor-team/wangEditor/commit/c65682743bd49eba9ab64be847f1f9527fb6170b))
* 修复 pnpm 安装 @wangeditor/editor 出现警告的问题 ([4087fbe](https://github.com/wangeditor-team/wangEditor/commit/4087fbee01c76bdd55e747a5e86c5e4a8d6a8353))
* 修复多选文字且选择空白行无法修改文字样式 ([99a9150](https://github.com/wangeditor-team/wangEditor/commit/99a91509c6e12220bb105cc6d15a0f0a4b375cea))
* 修复光标状态下设置文字样式,菜单不 active 的问题 ([b1b2dba](https://github.com/wangeditor-team/wangEditor/commit/b1b2dbaaae11f74bd36ec79ff50de336c252fef5))
* 修复清除格式不完全的问题 ([1181a23](https://github.com/wangeditor-team/wangEditor/commit/1181a23e6de71162dc490d9b348379c9b2ef4251))
* 修复设置文字颜色与背景色行为与预期不一致的问题 ([25d3381](https://github.com/wangeditor-team/wangEditor/commit/25d3381aa65ce8fe862617e7b1b03cfa5370715d))
* 选中文字,创建链接(同时修改文字) ([5fdf6ae](https://github.com/wangeditor-team/wangEditor/commit/5fdf6ae33b1bebe9b7373e4b7ee8c568480a3c08))
* 移除了每个包下的 publishConfig directory 配置 ([16559f0](https://github.com/wangeditor-team/wangEditor/commit/16559f052545c111318be760e64291a521bdcc65))
* 优化 custom-types.d.ts 中类型声明,修复测试文件 ts 报错 ([3a6c455](https://github.com/wangeditor-team/wangEditor/commit/3a6c4553245bc734dae1e17d605af389971782a2))
* 有内联元素时对齐失败 ([076c694](https://github.com/wangeditor-team/wangEditor/commit/076c694a4b3474080b89f52692595b84bf4d8207))
* blockquote & header insertBreak ([06678c9](https://github.com/wangeditor-team/wangEditor/commit/06678c963e8c8421ecded448de7510b254117550))
* code node 顶层 ([a927938](https://github.com/wangeditor-team/wangEditor/commit/a9279388f14212319505f6a5da300cd15e81c214))
* code-block 换行 - 自动加入前面的空格 ([c214032](https://github.com/wangeditor-team/wangEditor/commit/c2140327842d803cd18a9acf47ec3225182bf940))
* color toHtml ([2c9718c](https://github.com/wangeditor-team/wangEditor/commit/2c9718cb2feb4dd0a7bf39238598707fa6d2bb21))
* delete divider ([f04cbd6](https://github.com/wangeditor-team/wangEditor/commit/f04cbd6009099629e3cd41be19d20b6788fe7f28))
* disabled - img 和 todo 可编辑 ([cf6a3f2](https://github.com/wangeditor-team/wangEditor/commit/cf6a3f2a1e05b6231f46aa74c422561e4147f7ae))
* divider - 键盘删除 ([31db059](https://github.com/wangeditor-team/wangEditor/commit/31db0593dbc77fba9b4a719bc0f48f1223afd680))
* emptyP toHtml 增加 br ([c347c29](https://github.com/wangeditor-team/wangEditor/commit/c347c2916416edc96a99d1bf53c0e18cd22d80f9))
* getHtml API ([c0b60cf](https://github.com/wangeditor-team/wangEditor/commit/c0b60cf47d8eaae4292265906fbe07875e1564c9))
* header 不禁用 bold ([f4cd3d0](https://github.com/wangeditor-team/wangEditor/commit/f4cd3d0b85725701c3ec650e4d6ae7d8831f5105))
* hoverbar 被点击多次隐藏 ([bf4fc19](https://github.com/wangeditor-team/wangEditor/commit/bf4fc193847e8caba3a67c8dd152eae4f1950c4f))
* hoverbar modal 重复创建 ([70d2b61](https://github.com/wangeditor-team/wangEditor/commit/70d2b618a0662c88cd5e6691f513009726ce1b9b))
* hoverbar show/hide ([c96bc83](https://github.com/wangeditor-team/wangEditor/commit/c96bc8378939fecd78807fea4f2b7e1eec2a9ea0))
* image 拖拽,设置最小值 ([0205023](https://github.com/wangeditor-team/wangEditor/commit/0205023d8c1ec3fafcba3a950afcaef9f5f5170f))
* insert link ([a104682](https://github.com/wangeditor-team/wangEditor/commit/a10468279f730c9a4216474cf3d44d41f124cb6b))
* insertHtml - 空行 ([53a8fbb](https://github.com/wangeditor-team/wangEditor/commit/53a8fbb5cf665ef0d6f7fd1c2fee73dba0d98e32))
* insertHtml - 空行 ([c61f415](https://github.com/wangeditor-team/wangEditor/commit/c61f415c41d393f203ae5e5c17d9167ec60a1824))
* justify - disable ([3a4b24e](https://github.com/wangeditor-team/wangEditor/commit/3a4b24e8e628024de248f0b52bb4066f626e7480))
* justify indent ([5a81e52](https://github.com/wangeditor-team/wangEditor/commit/5a81e527a45e7a92eb36a2aefa50d93e20c4cec2))
* justify menu disabled ([19e2f80](https://github.com/wangeditor-team/wangEditor/commit/19e2f8008a435101c6ecd4d4a7eadd423cb1070f))
* link 无文本 ([af4fb32](https://github.com/wangeditor-team/wangEditor/commit/af4fb3218bd4651763f66c804fec2b872e99e8f3))
* link, text hoverbar 选区问题 ([e0b7438](https://github.com/wangeditor-team/wangEditor/commit/e0b7438c89a347f1b0b940d9c11150b72d595529))
* lodash.throttle 引用 bug ([50aeff9](https://github.com/wangeditor-team/wangEditor/commit/50aeff94859bf328346cb9cfe89d0abd57c3b641))
* maxLength - 拼音 + 粘贴 ([3ac4db6](https://github.com/wangeditor-team/wangEditor/commit/3ac4db6d78cbe7a8d1fe19747deb0a17edd9b552))
* menu active ([10829e2](https://github.com/wangeditor-team/wangEditor/commit/10829e2e9e1d864d4900821ee3d5fa516b8cca2a))
* parse html - 有些 elem children 需要过滤 ([63cbb80](https://github.com/wangeditor-team/wangEditor/commit/63cbb804c8c7a778a4ee1f4ba8717a11b4b6b5a3))
* parse-html - sub sup ([2c15a5f](https://github.com/wangeditor-team/wangEditor/commit/2c15a5f9c9c2de8b34770a6bebfe765d203a03f6))
* parse-html pre/code ([d9bd773](https://github.com/wangeditor-team/wangEditor/commit/d9bd773f9a40f9531d9163700253d0b5f717afb8))
* rename es module filename ([1821d4e](https://github.com/wangeditor-team/wangEditor/commit/1821d4eef49e64efcb41b848849ca7a5e6472044))
* shadow dom 中 modal 输入框异常 ([ef3b199](https://github.com/wangeditor-team/wangEditor/commit/ef3b199a3e74c6b8ba61ed781e1aa13a1c5acfde))
* style-to-html - 输入 a 会删除外部的 <a> 标签 ([af1f523](https://github.com/wangeditor-team/wangEditor/commit/af1f523983f2bc4b7eaf9726d4b8a35227ab27dc))
* table - elemToHtml ([e36e609](https://github.com/wangeditor-team/wangEditor/commit/e36e6092ef721723169afc8bf0560a47ac9f4dfc))
* tableCell 中 br 报错 ([8604db7](https://github.com/wangeditor-team/wangEditor/commit/8604db751b622c01fa5391af59328236cf13effc))


### Features

* 两端对齐 ([e5080d3](https://github.com/wangeditor-team/wangEditor/commit/e5080d3dd102f7a951d8e1f370db834778ecbdfa))
* 上标 下标 ([40dab08](https://github.com/wangeditor-team/wangEditor/commit/40dab085a061ea3e838f0cfa86260c6c6f894c69))
* 增加 enable disable API(删除 setConfig setMenuConfig API) ([984fc50](https://github.com/wangeditor-team/wangEditor/commit/984fc50520061fc34ea08f4136bdeb93dee46564))
* 增加 header4 header5 ([cc48734](https://github.com/wangeditor-team/wangEditor/commit/cc4873412ce3f4de1ecc1dbf4c313094dceb5a77))
* 支持 nodejs 环境 ([484f18c](https://github.com/wangeditor-team/wangEditor/commit/484f18c3abc70d19e51c556f48491c18d390b1e1))
* basic text paste ([f0a5b98](https://github.com/wangeditor-team/wangEditor/commit/f0a5b980c95fa1e2fc59a898c6e0d0723c276c28))
* clearStyle menu ([8002f70](https://github.com/wangeditor-team/wangEditor/commit/8002f707ed04b914180ec36fdca0edf48c815e01))
* drag resize image ([cd72028](https://github.com/wangeditor-team/wangEditor/commit/cd72028f1786e2e53079ad5cbef1b8569731ca79))
* editor 生命周期,自定义事件 ([00e9bc2](https://github.com/wangeditor-team/wangEditor/commit/00e9bc2cfcb8b622764db1c76394491d72ffd93e))
* focus支持focus到文档末尾 ([628830e](https://github.com/wangeditor-team/wangEditor/commit/628830ef06ff85b3e67001ce30dd9e0557b0aa28))
* fullScreen ([e7ccd88](https://github.com/wangeditor-team/wangEditor/commit/e7ccd88a7dd58f64b7bd484de428e3a76cc994f7))
* getHeaders & editor.srcollToElem ([2bfb813](https://github.com/wangeditor-team/wangEditor/commit/2bfb813e4957f080c6676ec38f8f051275cdf44a))
* groupButton disabled ([8ffd44c](https://github.com/wangeditor-team/wangEditor/commit/8ffd44c9a44758e951ca7bd02dd46746fcac1c03))
* header button menu ([6413135](https://github.com/wangeditor-team/wangEditor/commit/64131354d54705e11fd6992fcf5a4389371c3560))
* i18n ([c11b244](https://github.com/wangeditor-team/wangEditor/commit/c11b2440f91b99d40bca18b675c66a22b6e160c9))
* image menu - width 50% 100% ([f9b4c68](https://github.com/wangeditor-team/wangEditor/commit/f9b4c68dff3232b50491b07949c20eb4c18baa6b))
* image menu config ([bb18774](https://github.com/wangeditor-team/wangEditor/commit/bb187740e9703b4a76cde4f5e4d32ac714aa793a))
* insertHtml - text style ([6f303c5](https://github.com/wangeditor-team/wangEditor/commit/6f303c5be81dc8763a28bc982928e5bc9f2936d9))
* link menu config ([fe6b6db](https://github.com/wangeditor-team/wangEditor/commit/fe6b6db62086a5014c25ea96aa9308c2028a5b60))
* parse html ([2a5eace](https://github.com/wangeditor-team/wangEditor/commit/2a5eace00f33cded50b68e8164748ec2480213fd))
* parse src (link image video) ([715a841](https://github.com/wangeditor-team/wangEditor/commit/715a841fc6c730ee2b448a1799a07ce778128aad))
* placeholder ([a3e4cdc](https://github.com/wangeditor-team/wangEditor/commit/a3e4cdcd474063e4f436327aaf4074bb2126d941))
* react 组件 ([448fc83](https://github.com/wangeditor-team/wangEditor/commit/448fc838d64dbef52cbcddde0e98eb021d8a9122))
* todo ([9608fef](https://github.com/wangeditor-team/wangEditor/commit/9608fef2ff86368cdcbb950a74af1246a58709de))
* toHtml 机制 ([1c4d872](https://github.com/wangeditor-team/wangEditor/commit/1c4d8729f84aaab6a448f23064b34a20596305e9))
* upload video ([ac8e6f8](https://github.com/wangeditor-team/wangEditor/commit/ac8e6f8b5258e593714676a6f6be359ba525833c))
* video menu config ([7fa3783](https://github.com/wangeditor-team/wangEditor/commit/7fa3783c42aa83f7d53c8be34be3c8b7c8a64754))


### Performance Improvements

* 优化较大的svg图片 ([2c360e7](https://github.com/wangeditor-team/wangEditor/commit/2c360e7628eb655e8df67cc7b764f4981b283a2f))


================================================
FILE: packages/basic-modules/README.md
================================================
# wangEditor basic-modules

Basic modules built in [wangEditor](https://www.wangeditor.com/) by default.


================================================
FILE: packages/basic-modules/__tests__/blockquote/blockquote-menu.test.ts
================================================
/**
 * @description blockquote menu test
 * @author wangfupeng
 */

import { Editor, Transforms } from 'slate'
import createEditor from '../../../../tests/utils/create-editor'
import BlockquoteMenu from '../../src/modules/blockquote/menu/BlockquoteMenu'

describe('blockquote menu', () => {
  let editor: any
  let startLocation: any
  const menu = new BlockquoteMenu()

  beforeEach(() => {
    editor = createEditor()
    startLocation = Editor.start(editor, [])
  })

  afterEach(() => {
    editor = null
    startLocation = null
  })

  // getValue 无逻辑,不用测试

  it('is disabled', () => {
    editor.select(startLocation)
    expect(menu.isDisabled(editor)).toBeFalsy()

    Transforms.setNodes(editor, { type: 'blockquote' })
    expect(menu.isDisabled(editor)).toBeFalsy()

    Transforms.setNodes(editor, { type: 'header1' })
    expect(menu.isDisabled(editor)).toBeTruthy() // 非 p blockquote ,则禁用
  })

  it('exec and isActive', () => {
    editor.select(startLocation)

    menu.exec(editor, '') // 转换为 blockquote
    const blockquotes1 = editor.getElemsByTypePrefix('blockquote')
    expect(blockquotes1.length).toBe(1)
    expect(menu.isActive(editor)).toBeTruthy()

    menu.exec(editor, '') // 取消 blockquote
    const blockquotes2 = editor.getElemsByTypePrefix('blockquote')
    expect(blockquotes2.length).toBe(0)
    expect(menu.isActive(editor)).toBeFalsy()
  })
})


================================================
FILE: packages/basic-modules/__tests__/blockquote/elem-to-html.test.ts
================================================
/**
 * @description blockquote - elem to html test
 * @author wangfupeng
 */

import { quoteToHtmlConf } from '../../src/modules/blockquote/elem-to-html'

describe('blockquote elem to html', () => {
  it('blockquote to html', () => {
    expect(quoteToHtmlConf.type).toBe('blockquote')

    const elem = { type: 'blockquote', children: [] }
    const html = quoteToHtmlConf.elemToHtml(elem, 'hello')
    expect(html).toBe('<blockquote>hello</blockquote>')
  })
})


================================================
FILE: packages/basic-modules/__tests__/blockquote/parse-html.test.ts
================================================
/**
 * @description parse html test
 * @author wangfupeng
 */

import { $ } from 'dom7'
import { BaseElement } from 'slate'
import createEditor from '../../../../tests/utils/create-editor'
import { parseHtmlConf } from '../../src/modules/blockquote/parse-elem-html'

describe('blockquote - parse html', () => {
  const editor = createEditor()

  it('without children', () => {
    const $elem = $('<blockquote>hello&nbsp;world</blockquote>')

    // match selector
    expect($elem[0].matches(parseHtmlConf.selector)).toBeTruthy()

    // parse
    const res = parseHtmlConf.parseElemHtml($elem[0], [], editor)
    expect(res).toEqual({
      type: 'blockquote',
      children: [{ text: 'hello world' }],
    })
  })

  it('with children', () => {
    const $elem = $('<blockquote></blockquote>')
    const children = [{ text: 'hello ' }, { text: 'world', bold: true }]

    // parse
    const res = parseHtmlConf.parseElemHtml($elem[0], children, editor)
    expect(res).toEqual({
      type: 'blockquote',
      children: [{ text: 'hello ' }, { text: 'world', bold: true }],
    })
  })

  it('with inline children', () => {
    const $elem = $('<blockquote></blockquote>')
    const children: any[] = [
      { text: 'hello ' },
      { type: 'link', url: 'http://wangeditor.com' },
      { type: 'paragraph', children: [] },
    ]

    const isInline = editor.isInline
    editor.isInline = (element: any) => {
      if (element.type === 'link') return true
      return isInline(element)
    }

    // parse
    const res = parseHtmlConf.parseElemHtml($elem[0], children, editor)
    expect(res).toEqual({
      type: 'blockquote',
      children: [{ text: 'hello ' }, { type: 'link', url: 'http://wangeditor.com' }],
    })
  })
})


================================================
FILE: packages/basic-modules/__tests__/blockquote/plugin.test.ts
================================================
/**
 * @description blockquote plugin test
 * @author wangfupeng
 */

import { Editor, Transforms } from 'slate'
import createEditor from '../../../../tests/utils/create-editor'
import withBlockquote from '../../src/modules/blockquote/plugin'

describe('blockquote plugin', () => {
  let editor = withBlockquote(createEditor())
  let startLocation = Editor.start(editor, [])

  beforeEach(() => {
    editor = withBlockquote(createEditor())
    startLocation = Editor.start(editor, [])
  })

  it('insert break', () => {
    expect(1).toBeTruthy()

    // TODO 该测试一直报错(找不到 blockquote path),待定处理
    // editor.select(startLocation)

    // // @ts-ignore
    // Transforms.setNodes(editor, { type: 'blockquote' }) // 设置 blockquote

    // const pList1 = editor.getElemsByType('paragraph')
    // expect(pList1.length).toBe(0)

    // editor.insertText('hello')
    // console.log(11, JSON.stringify(editor.children))
    // console.log(22, JSON.stringify(editor.selection))
    // editor.insertBreak() // 第一次换行,内部插入 \n

    // const pList2 = editor.getElemsByType('paragraph')
    // expect(pList2.length).toBe(0)

    // editor.insertBreak() // 再一次换行,生成 p
    // const pList3 = editor.getElemsByType('paragraph')
    // expect(pList3.length).toBe(1)
  })
})


================================================
FILE: packages/basic-modules/__tests__/blockquote/render-elem.test.ts
================================================
/**
 * @description blockquote render elem test
 * @author wangfupeng
 */

import createEditor from '../../../../tests/utils/create-editor'
import { renderBlockQuoteConf } from '../../src/modules/blockquote/render-elem'

describe('blockquote - render elem', () => {
  const editor = createEditor()

  it('render blockquote elem', () => {
    expect(renderBlockQuoteConf.type).toBe('blockquote')

    const elem = { type: 'blockquote', children: [] }
    const vnode = renderBlockQuoteConf.renderElem(elem, null, editor)
    expect(vnode.sel).toBe('blockquote')
  })
})


================================================
FILE: packages/basic-modules/__tests__/code-block/code-block-menu.test.ts
================================================
/**
 * @description code-block menu test
 * @author wangfupeng
 */

import { Editor, Transforms, Element } from 'slate'
import createEditor from '../../../../tests/utils/create-editor'
import CodeBlockMenu from '../../src/modules/code-block/menu/CodeBlockMenu'

describe('code-block menu', () => {
  const menu = new CodeBlockMenu()
  let editor: any
  let startLocation: any

  const codeElem = {
    type: 'code',
    language: 'javascript',
    children: [{ text: 'var' }],
  }
  const preElem = {
    type: 'pre',
    children: [codeElem],
  }

  beforeEach(() => {
    editor = createEditor()
    startLocation = Editor.start(editor, [])
  })

  afterEach(() => {
    editor = null
    startLocation = null
  })

  it('getValue and isActive', done => {
    editor.select(startLocation)
    expect(menu.isActive(editor)).toBeFalsy()
    expect(menu.getValue(editor)).toBe('')

    editor.insertNode(preElem) // 插入 code node
    editor.select({
      path: [1, 0, 0], // 选中 code node
      offset: 3,
    })
    setTimeout(() => {
      expect(menu.isActive(editor)).toBeTruthy()
      expect(menu.getValue(editor)).toBe('javascript')
      done()
    })
  })

  it('is disabled', () => {
    editor.select(startLocation)
    expect(menu.isDisabled(editor)).toBeFalsy()

    Transforms.setNodes(editor, { type: 'header1' } as Partial<Element>)
    expect(menu.isDisabled(editor)).toBeTruthy() // 非 p pre ,则禁用

    editor.insertNode({ type: 'pre', children: [{ type: 'code', children: [{ text: 'var' }] }] })
    expect(menu.isDisabled(editor)).toBeFalsy()
    // Transforms.removeNodes(editor, { mode: 'highest' }) // 移除 pre/code
  })

  it('exec - to code-block', () => {
    editor.select(startLocation)

    menu.exec(editor, 'javascript') // 生成 code-block
    const preList = editor.getElemsByTypePrefix('pre')
    expect(preList.length).toBe(1)
    const codeLis = editor.getElemsByTypePrefix('code')
    expect(codeLis.length).toBe(1)
  })

  it('exec - to paragraph', () => {
    editor.select(startLocation)
    editor.insertNode(preElem) // 插入 code node
    editor.select({
      path: [1, 0, 0], // 选中 code node
      offset: 3,
    })

    menu.exec(editor, '') // 取消 code-block
    const preList = editor.getElemsByTypePrefix('pre')
    expect(preList.length).toBe(0)
    const codeLis = editor.getElemsByTypePrefix('code')
    expect(codeLis.length).toBe(0)
  })
})


================================================
FILE: packages/basic-modules/__tests__/code-block/elem-to-html.test.ts
================================================
/**
 * @description code-block elem to html test
 * @author wangfupeng
 */

import { codeToHtmlConf, preToHtmlConf } from '../../src/modules/code-block/elem-to-html'

describe('code-block - elem to html', () => {
  it('code to html', () => {
    expect(codeToHtmlConf.type).toBe('code')
    const elem = { type: 'code', children: [] }
    const html = codeToHtmlConf.elemToHtml(elem, 'hello')
    expect(html).toBe('<code>hello</code>')
  })

  it('pre to html', () => {
    expect(preToHtmlConf.type).toBe('pre')
    const elem = { type: 'pre', children: [] }
    const html = preToHtmlConf.elemToHtml(elem, 'hello')
    expect(html).toBe('<pre>hello</pre>')
  })
})


================================================
FILE: packages/basic-modules/__tests__/code-block/parse-html.test.ts
================================================
/**
 * @description parse elem html
 * @author wangfupeng
 */

import { $ } from 'dom7'
import createEditor from '../../../../tests/utils/create-editor'
import { parseCodeHtmlConf, parsePreHtmlConf } from '../../src/modules/code-block/parse-elem-html'
import { preParseHtmlConf } from '../../src/modules/code-block/pre-parse-html'

describe('code block - pre parse html', () => {
  it('pre parse html', () => {
    const $pre = $('<pre></pre>')
    const $code = $('<code><xmp>var a = 100;</xmp></code>')
    $pre.append($code)

    // match selector
    expect($code[0].matches(preParseHtmlConf.selector)).toBeTruthy()

    // pre parse
    const res = preParseHtmlConf.preParseHtml($code[0])
    expect(res.innerHTML).toBe('var a = 100;')
  })
})

describe('code block - parse html', () => {
  const editor = createEditor()

  it('parse code html', () => {
    const $pre = $('<pre></pre>')
    const $code = $('<code><xmp>var a = 100;</xmp></code>')
    $pre.append($code)

    // match selector
    expect($code[0].matches(parseCodeHtmlConf.selector)).toBeTruthy()

    // parse
    const res = parseCodeHtmlConf.parseElemHtml($code[0], [], editor)
    expect(res).toEqual({
      type: 'code',
      language: '',
      children: [{ text: 'var a = 100;' }],
    })
  })
  it('parse pre html', () => {
    const $pre = $('<pre></pre>')
    const children = [
      {
        type: 'code',
        language: '',
        children: [{ text: 'var a = 100;' }],
      },
    ]

    // match selector
    expect($pre[0].matches(parsePreHtmlConf.selector)).toBeTruthy()

    // parse
    const res = parsePreHtmlConf.parseElemHtml($pre[0], children, editor)
    expect(res).toEqual({
      type: 'pre',
      children: [
        {
          type: 'code',
          language: '',
          children: [{ text: 'var a = 100;' }],
        },
      ],
    })
  })
})


================================================
FILE: packages/basic-modules/__tests__/code-block/plugin.test.ts
================================================
/**
 * @description code-block plugin test
 * @author wangfupeng
 */

import { Editor, Transforms } from 'slate'
import createEditor from '../../../../tests/utils/create-editor'
import withCodeBlock from '../../src/modules/code-block/plugin'

// 模拟 DataTransfer
class MyDataTransfer {
  private values: object = {}
  setData(type: string, value: string) {
    this.values[type] = value
  }
  getData(type: string): string {
    return this.values[type]
  }
}

describe('code-block plugin', () => {
  let editor: any
  let startLocation: any

  const codeElem = {
    type: 'code',
    children: [{ text: 'var' }],
  }
  const preElem = {
    type: 'pre',
    children: [codeElem],
  }

  beforeEach(() => {
    editor = withCodeBlock(createEditor())
    startLocation = Editor.start(editor, [])
  })

  afterEach(() => {
    editor = null
    startLocation = null
  })

  it('insert break', () => {
    editor.select(startLocation)
    editor.insertNode(preElem) // 插入 code-block

    // code-block 前后会自动生成两个 p
    const pList1 = editor.getElemsByTypePrefix('paragraph')
    expect(pList1.length).toBe(2)

    editor.select({
      path: [1, 0, 0], // 选中 code-block
      offset: 3,
    })

    // 换行都在 code-block 内部
    editor.insertBreak()
    editor.insertBreak()
    editor.insertBreak()
    expect(editor.getText()).toBe('\nvar\n\n\n\n')

    // 不会再生成新的 p
    const pList2 = editor.getElemsByTypePrefix('paragraph')
    expect(pList2.length).toBe(2)
  })

  it('insert data', () => {
    editor.select(startLocation)
    editor.insertNode(preElem) // 插入 code node
    editor.select({
      path: [1, 0, 0], // 选中 code node
      offset: 3,
    })

    const data = new MyDataTransfer()
    data.setData('text/plain', ' hello')

    editor.insertData(data)
    expect(editor.getText()).toBe('\nvar hello\n')
  })

  it('normalizeNode - code node 不能是顶级元素,否则替换为 p', () => {
    editor.select(startLocation)
    editor.insertNode(codeElem)

    const pList = editor.getElemsByTypePrefix('paragraph')
    expect(pList.length).toBe(2)
  })

  it('normalizeNode - pre node 不能是第一个节点,否则前面插入 p', () => {
    editor.select(startLocation)
    editor.insertNode({ type: 'pre', children: [{ type: 'code', children: [{ text: 'var' }] }] })

    const pList = editor.getElemsByTypePrefix('paragraph')
    expect(pList.length).toBe(2)

    const preList = editor.getElemsByTypePrefix('pre')
    expect(preList.length).toBe(1)
  })
})


================================================
FILE: packages/basic-modules/__tests__/code-block/render-elem.test.ts
================================================
/**
 * @description code-block render elem test
 * @author wangfupeng
 */

import createEditor from '../../../../tests/utils/create-editor'
import { renderPreConf, renderCodeConf } from '../../src/modules/code-block/render-elem'

describe('code-block render elem', () => {
  const editor = createEditor()

  it('render code elem', () => {
    expect(renderCodeConf.type).toBe('code')

    const elem = { type: 'code', children: [] }
    const vnode = renderCodeConf.renderElem(elem, null, editor)
    expect(vnode.sel).toBe('code')
  })

  it('render pre elem', () => {
    expect(renderPreConf.type).toBe('pre')

    const elem = { type: 'pre', children: [] }
    const vnode = renderPreConf.renderElem(elem, null, editor)
    expect(vnode.sel).toBe('pre')
  })
})


================================================
FILE: packages/basic-modules/__tests__/color/color-menus.test.ts
================================================
/**
 * @description color menus test
 * @author wangfupeng
 */

import { Editor, Transforms } from 'slate'
import createEditor from '../../../../tests/utils/create-editor'
import ColorMenu from '../../src/modules/color/menu/ColorMenu'
import BgColorMenu from '../../src/modules/color/menu/BgColorMenu'

describe('color menus', () => {
  let editor: any
  let startLocation: any

  const menus = [
    {
      mark: 'color',
      menu: new ColorMenu(),
    },
    {
      mark: 'bgColor',
      menu: new BgColorMenu(),
    },
  ]

  beforeEach(() => {
    editor = createEditor()
    startLocation = Editor.start(editor, [])
  })

  afterEach(() => {
    editor = null
    startLocation = null
  })

  // exec 无代码,不用测试

  it('getValue and isActive', () => {
    editor.select(startLocation)

    menus.forEach(({ menu }) => {
      expect(menu.getValue(editor)).toBe('')
      expect(menu.isActive(editor)).toBeFalsy()
    })

    editor.insertText('hello') // 插入文字
    editor.select([]) // 全选
    menus.forEach(({ mark, menu }) => {
      editor.addMark(mark, 'rgb(51, 51, 51)') // 添加 color bgColor
      expect(menu.getValue(editor)).toBe('rgb(51, 51, 51)')
      expect(menu.isActive(editor)).toBeTruthy()
    })
  })

  it('is disabled', () => {
    editor.select(startLocation)
    menus.forEach(({ menu }) => {
      expect(menu.isDisabled(editor)).toBeFalsy()
    })

    editor.insertNode({ type: 'pre', children: [{ type: 'code', children: [{ text: 'var' }] }] })
    menus.forEach(({ menu }) => {
      expect(menu.isDisabled(editor)).toBeTruthy()
    })
    // Transforms.removeNodes(editor, { mode: 'highest' }) // 移除 pre/code
  })

  it('get panel content elem', () => {
    menus.forEach(({ menu }) => {
      const elem = menu.getPanelContentElem(editor)
      expect(elem instanceof HTMLElement).toBeTruthy()
    })
  })
})


================================================
FILE: packages/basic-modules/__tests__/color/parse-html.test.ts
================================================
/**
 * @description parse html test
 * @author wangfupeng
 */

import { $ } from 'dom7'
import createEditor from '../../../../tests/utils/create-editor'
import { parseStyleHtml } from '../../src/modules/color/parse-style-html'
import { preParseHtmlConf } from '../../src/modules/color/pre-parse-html'

describe('color - pre parse html', () => {
  it('pre parse html', () => {
    const $font = $('<font color="rgb(204, 204, 204)">hello</font>')

    // match selector
    expect($font[0].matches(preParseHtmlConf.selector)).toBeTruthy()

    // pre parse
    const res = preParseHtmlConf.preParseHtml($font[0])
    expect(res.outerHTML).toBe('<font style="color: rgb(204, 204, 204);">hello</font>')
  })
})

describe('color - parse style html', () => {
  const editor = createEditor()

  it('parse style html', () => {
    const $span = $(
      '<span style="color: rgb(235, 144, 58); background-color: rgb(231, 246, 213);"></span>'
    )
    const textNode = { text: 'hello' }

    // parse style
    const res = parseStyleHtml($span[0], textNode, editor)
    expect(res).toEqual({
      text: 'hello',
      color: 'rgb(235, 144, 58)',
      bgColor: 'rgb(231, 246, 213)',
    })
  })
})


================================================
FILE: packages/basic-modules/__tests__/color/render-text-style.test.tsx
================================================
/**
 * @description color - render text style test
 * @author wangfupeng
 */

import { jsx } from 'snabbdom'
import { renderStyle } from '../../src/modules/color/render-style'

describe('color - render text style', () => {
  it('render color style', () => {
    const color = 'rgb(51, 51, 51)'
    const bgColor = 'rgb(204, 204, 204)'
    const textNode = { text: 'hello', color, bgColor }
    const vnode = <span>hello</span>

    // @ts-ignore
    const newVnode = renderStyle(textNode, vnode) as any
    expect(newVnode.sel).toBe('span')
    expect(newVnode.data.style.color).toBe(color)
    expect(newVnode.data.style.backgroundColor).toBe(bgColor)
  })
})


================================================
FILE: packages/basic-modules/__tests__/color/text-style-to-html.test.ts
================================================
/**
 * @description color - text style to html test
 * @author wangfupeng
 */

import { styleToHtml } from '../../src/modules/color/style-to-html'

describe('color - text style to html', () => {
  it('color to html', () => {
    const color = 'rgb(51, 51, 51)'
    const bgColor = 'rgb(204, 204, 204)'
    const textNode = { text: '', color, bgColor }

    const html = styleToHtml(textNode, '<span>hello</span>')
    expect(html).toBe(`<span style="color: ${color}; background-color: ${bgColor};">hello</span>`)
  })
})


================================================
FILE: packages/basic-modules/__tests__/divider/elem-to-html.test.ts
================================================
/**
 * @description divider - elem to html test
 * @author wangfupeng
 */

import { dividerToHtmlConf } from '../../src/modules/divider/elem-to-html'

describe('divider - elem to html', () => {
  it('divider to html', () => {
    expect(dividerToHtmlConf.type).toBe('divider')

    const elem = { type: 'divider', children: [{ text: '' }] }
    const html = dividerToHtmlConf.elemToHtml(elem, '')
    expect(html).toBe('<hr/>')
  })
})


================================================
FILE: packages/basic-modules/__tests__/divider/insert-divider-menu.test.ts
================================================
/**
 * @description insert divider menu test
 * @author wangfupeng
 */

import { Editor } from 'slate'
import createEditor from '../../../../tests/utils/create-editor'
import InsertDividerMenu from '../../src/modules/divider/menu/InsertDividerMenu'

describe('divider plugin', () => {
  const menu = new InsertDividerMenu()
  let editor: any
  let startLocation: any

  beforeEach(() => {
    editor = createEditor()
    startLocation = Editor.start(editor, [])
  })

  afterEach(() => {
    editor = null
    startLocation = null
  })

  // getValue isActive 无逻辑,不用测试

  it('is disabled', () => {
    editor.deselect()
    expect(menu.isDisabled(editor)).toBeTruthy()

    editor.select(startLocation)
    expect(menu.isDisabled(editor)).toBeFalsy()

    const elem = { type: 'divider', children: [{ text: '' }] }
    editor.insertNode(elem) // 插入 divider
    editor.select({
      path: [1, 0], // 选中 divider
      offset: 0,
    })
    expect(menu.isDisabled(editor)).toBeTruthy()
  })

  it('exec', () => {
    editor.select(startLocation)
    menu.exec(editor, '')

    const dividers = editor.getElemsByTypePrefix('divider')
    expect(dividers.length).toBe(1)
  })
})


================================================
FILE: packages/basic-modules/__tests__/divider/parse-html.test.ts
================================================
/**
 * @description parse html test
 * @author wangfupeng
 */

import { $ } from 'dom7'
import createEditor from '../../../../tests/utils/create-editor'
import { parseHtmlConf } from '../../src/modules/divider/parse-elem-html'

describe('divider - parse html', () => {
  const editor = createEditor()

  it('parse html', () => {
    const $hr = $('<hr>')

    // match selector
    expect($hr[0].matches(parseHtmlConf.selector)).toBeTruthy()

    // parse
    const res = parseHtmlConf.parseElemHtml($hr[0], [], editor)
    expect(res).toEqual({
      type: 'divider',
      children: [{ text: '' }], // void node 有一个空白 text
    })
  })
})


================================================
FILE: packages/basic-modules/__tests__/divider/plugin.test.ts
================================================
/**
 * @description divider plugin test
 * @author wangfupeng
 */

import { Editor } from 'slate'
import createEditor from '../../../../tests/utils/create-editor'
import withDivider from '../../src/modules/divider/plugin'

describe('divider plugin', () => {
  let editor: any
  let startLocation: any

  beforeEach(() => {
    editor = withDivider(createEditor())
    startLocation = Editor.start(editor, [])
  })

  afterEach(() => {
    editor = null
    startLocation = null
  })

  it('divider is void node', () => {
    const elem = { type: 'divider', children: [{ text: '' }] }
    expect(editor.isVoid(elem)).toBeTruthy()
  })

  it('normalizeNode - divider 不能是最后一个元素,否则后面追加 p', () => {
    const elem = { type: 'divider', children: [{ text: '' }] }
    editor.select(startLocation)
    editor.insertNode(elem) // 插入 divider

    const length = editor.children.length
    expect(length).toBe(3) // 3 个顶级节点:p, divider, p

    const divider = editor.children[1] // 第 2 个节点应该是 divider
    expect(divider.type).toBe('divider')
    const p = editor.children[2] // 第 3 个节点应该是 p
    expect(p.type).toBe('paragraph')
  })
})


================================================
FILE: packages/basic-modules/__tests__/divider/render-elem.test.ts
================================================
/**
 * @description divider - render elem test
 * @author wangfupeng
 */

import { Editor } from 'slate'
import createEditor from '../../../../tests/utils/create-editor'
import { renderDividerConf } from '../../src/modules/divider/render-elem'

describe('divider - render elem test', () => {
  const editor = createEditor()
  const startLocation = Editor.start(editor, [])

  it('render divider elem', () => {
    expect(renderDividerConf.type).toBe('divider')

    const elem = { type: 'divider', children: [{ text: '' }] }
    const vnode1 = renderDividerConf.renderElem(elem, null, editor) as any
    expect(vnode1.sel).toBe('div')
    expect(vnode1.data.props.className).toBe('w-e-textarea-divider')
    expect(vnode1.data.dataset.selected).toBe('') // 未选中
    expect(vnode1.children[0].sel).toBe('hr')

    editor.select(startLocation)
    editor.insertNode(elem) // 插入 divider
    editor.select({
      path: [1, 0], // 选中 divider
      offset: 0,
    })
    const vnode2 = renderDividerConf.renderElem(elem, null, editor) as any
    expect(vnode2.data.dataset.selected).toBe('true') // 选中
  })
})


================================================
FILE: packages/basic-modules/__tests__/emotion/emotion-menu.test.ts
================================================
/**
 * @description emotion menu test
 * @author wangfupeng
 */

import { Editor, Transforms } from 'slate'
import createEditor from '../../../../tests/utils/create-editor'
import EmotionMenu from '../../src/modules/emotion/menu/EmotionMenu'

describe('font family menu', () => {
  const menu = new EmotionMenu()
  let editor: any
  let startLocation: any

  beforeEach(() => {
    editor = createEditor()
    startLocation = Editor.start(editor, [])
  })

  afterEach(() => {
    editor = null
    startLocation = null
  })

  // exec getValue isActive 无代码逻辑,不用测试

  it('is disabled', () => {
    editor.select(startLocation)
    expect(menu.isDisabled(editor)).toBeFalsy()

    editor.insertNode({ type: 'pre', children: [{ type: 'code', children: [{ text: 'var' }] }] })
    expect(menu.isDisabled(editor)).toBeTruthy()
    // Transforms.removeNodes(editor, { mode: 'highest' }) // 移除 pre/code
  })

  it('get panel content elem', () => {
    const elem = menu.getPanelContentElem(editor)
    expect(elem instanceof HTMLElement).toBeTruthy()
  })
})


================================================
FILE: packages/basic-modules/__tests__/font-size-family/menu/font-family-menu.test.ts
================================================
/**
 * @description font family menu test
 * @author wangfupeng
 */

import { Editor, Transforms } from 'slate'
import createEditor from '../../../../../tests/utils/create-editor'
import FontFamilyMenu from '../../../src/modules/font-size-family/menu/FontFamilyMenu'

describe('font family menu', () => {
  const menu = new FontFamilyMenu()
  let editor: any
  let startLocation: any

  beforeEach(() => {
    editor = createEditor()
    startLocation = Editor.start(editor, [])
  })

  afterEach(() => {
    editor = null
    startLocation = null
  })

  it('get options', () => {
    editor.select(startLocation)
    const options1 = menu.getOptions(editor)
    const selectedDefault = options1.some(opt => opt.selected && opt.value === '')
    expect(selectedDefault).toBeTruthy() // 空白 p ,选中“默认”

    editor.insertText('hello')
    editor.select([]) // 全选
    editor.addMark('fontFamily', '黑体') // 设置字体
    const options2 = menu.getOptions(editor)
    const selectedHeiti = options2.some(opt => opt.selected && opt.value === '黑体')
    expect(selectedHeiti).toBeTruthy()
  })

  // isActive 无代码逻辑,不用测试

  it('is disabled', () => {
    editor.select(startLocation)
    expect(menu.isDisabled(editor)).toBeFalsy()

    editor.insertNode({ type: 'pre', children: [{ type: 'code', children: [{ text: 'var' }] }] })
    expect(menu.isDisabled(editor)).toBeTruthy()
    // Transforms.removeNodes(editor, { mode: 'highest' }) // 移除 pre/code
  })

  it('exec and getValue', () => {
    editor.select(startLocation)
    expect(menu.getValue(editor)).toBe('')

    editor.insertText('hello')
    editor.select([]) // 全选
    menu.exec(editor, '黑体') // 设置字体
    expect(menu.getValue(editor)).toBe('黑体')

    menu.exec(editor, '') // 取消字体
    expect(menu.getValue(editor)).toBe('')
  })
})


================================================
FILE: packages/basic-modules/__tests__/font-size-family/menu/font-size-menu.test.ts
================================================
/**
 * @description font size menu test
 * @author wangfupeng
 */

import { Editor, Transforms } from 'slate'
import createEditor from '../../../../../tests/utils/create-editor'
import FontSizeMenu from '../../../src/modules/font-size-family/menu/FontSizeMenu'

describe('font family menu', () => {
  const menu = new FontSizeMenu()
  let editor: any
  let startLocation: any

  beforeEach(() => {
    editor = createEditor()
    startLocation = Editor.start(editor, [])
  })

  afterEach(() => {
    editor = null
    startLocation = null
  })

  it('get options', () => {
    editor.select(startLocation)
    const options1 = menu.getOptions(editor)
    const selectedDefault = options1.some(opt => opt.selected && opt.value === '')
    expect(selectedDefault).toBeTruthy() // 空白 p ,选中“默认”

    editor.insertText('hello')
    editor.select([]) // 全选
    editor.addMark('fontSize', '40px') // 设置字号
    const options2 = menu.getOptions(editor)
    const selected = options2.some(opt => opt.selected && opt.value === '40px')
    expect(selected).toBeTruthy()
  })

  // isActive 无代码逻辑,不用测试

  it('is disabled', () => {
    editor.select(startLocation)
    expect(menu.isDisabled(editor)).toBeFalsy()

    editor.insertNode({ type: 'pre', children: [{ type: 'code', children: [{ text: 'var' }] }] })
    expect(menu.isDisabled(editor)).toBeTruthy()
    // Transforms.removeNodes(editor, { mode: 'highest' }) // 移除 pre/code
  })

  it('exec and getValue', () => {
    editor.select(startLocation)
    expect(menu.getValue(editor)).toBe('')

    editor.insertText('hello')
    editor.select([]) // 全选
    menu.exec(editor, '40px') // 设置字号
    expect(menu.getValue(editor)).toBe('40px')

    menu.exec(editor, '') // 取消字号
    expect(menu.getValue(editor)).toBe('')
  })
})


================================================
FILE: packages/basic-modules/__tests__/font-size-family/parse-html.test.ts
================================================
/**
 * @description parse html test
 * @author wangfupeng
 */

import { $ } from 'dom7'
import createEditor from '../../../../tests/utils/create-editor'
import { parseStyleHtml } from '../../src/modules/font-size-family/parse-style-html'
import { preParseHtmlConf } from '../../src/modules/font-size-family/pre-parse-html'

describe('font size family - pre parse html', () => {
  it('pre parse html', () => {
    const $font = $('<font size="1" face="黑体">hello</font>')

    // match selector
    expect($font[0].matches(preParseHtmlConf.selector)).toBeTruthy()

    // pre parse
    const res = preParseHtmlConf.preParseHtml($font[0])
    expect(res.outerHTML).toBe('<font style="font-size: 12px; font-family: 黑体;">hello</font>')
  })
})

describe('font size family - parse style html', () => {
  const editor = createEditor()

  it('parse style html', () => {
    const $span = $('<span style="font-size: 12px; font-family: 黑体;"></span>')
    const textNode = { text: 'hello' }

    // parse style
    const res = parseStyleHtml($span[0], textNode, editor)
    expect(res).toEqual({
      text: 'hello',
      fontSize: '12px',
      fontFamily: '黑体',
    })
  })
})


================================================
FILE: packages/basic-modules/__tests__/font-size-family/render-text-style.test.tsx
================================================
/**
 * @description font size and family - render text style test
 * @author wangfupeng
 */

import { jsx } from 'snabbdom'
import { renderStyle } from '../../src/modules/font-size-family/render-style'

describe('font size and family - render text style', () => {
  it('render text style', () => {
    const fontSize = '20px'
    const fontFamily = '黑体'
    const textNode = { text: 'hello', fontSize, fontFamily }
    const vnode = <span>hello</span>

    // @ts-ignore 忽略 vnode 格式检查
    const newVnode = renderStyle(textNode, vnode) as any
    expect(newVnode.data.style.fontSize).toBe(fontSize)
    expect(newVnode.data.style.fontFamily).toBe(fontFamily)
  })
})


================================================
FILE: packages/basic-modules/__tests__/font-size-family/text-style-to-html.test.ts
================================================
/**
 * @description font size and family - text style to html test
 * @author wangfupeng
 */

import { styleToHtml } from '../../src/modules/font-size-family/style-to-html'

describe('font size and family - text style to html', () => {
  it('text style to html', () => {
    const fontSize = '20px'
    const fontFamily = '黑体'
    const textNode = { text: '', fontSize, fontFamily }

    const html = styleToHtml(textNode, '<span>hello</span>')
    expect(html).toBe(
      `<span style="font-size: ${fontSize}; font-family: ${fontFamily};">hello</span>`
    )
  })
})


================================================
FILE: packages/basic-modules/__tests__/full-screen/full-screen-menu.test.ts
================================================
/**
 * @description full screen menu test
 * @author wangfupeng
 */

import createEditor from '../../../../tests/utils/create-editor'
import FullScreen from '../../src/modules/full-screen/menu/FullScreen'

describe('full screen menu', () => {
  const editor = createEditor()
  const menu = new FullScreen()

  it('full screen menu', done => {
    menu.exec(editor, '') // 设置全屏
    expect(menu.isActive(editor)).toBeTruthy()

    menu.exec(editor, '') // 取消全屏(有延迟)
    setTimeout(() => {
      expect(menu.isActive(editor)).toBeFalsy()
      done()
    }, 500)
  })
})


================================================
FILE: packages/basic-modules/__tests__/header/elem-to-html.test.ts
================================================
/**
 * @description header - elem to html test
 * @author wangfupeng
 */

import {
  header1ToHtmlConf,
  header2ToHtmlConf,
  header3ToHtmlConf,
  header4ToHtmlConf,
  header5ToHtmlConf,
} from '../../src/modules/header/elem-to-html'

describe('header - elem to html', () => {
  const elem = { type: 'header1', children: [{ text: '' }] }
  it('header1 to html', () => {
    expect(header1ToHtmlConf.type).toBe('header1')
    const html = header1ToHtmlConf.elemToHtml(elem, 'hello')
    expect(html).toBe('<h1>hello</h1>')
  })

  it('header2 to html', () => {
    expect(header2ToHtmlConf.type).toBe('header2')
    const html = header2ToHtmlConf.elemToHtml(elem, 'hello')
    expect(html).toBe('<h2>hello</h2>')
  })

  it('header3 to html', () => {
    expect(header3ToHtmlConf.type).toBe('header3')
    const html = header3ToHtmlConf.elemToHtml(elem, 'hello')
    expect(html).toBe('<h3>hello</h3>')
  })

  it('header4 to html', () => {
    expect(header4ToHtmlConf.type).toBe('header4')
    const html = header4ToHtmlConf.elemToHtml(elem, 'hello')
    expect(html).toBe('<h4>hello</h4>')
  })

  it('header5 to html', () => {
    expect(header5ToHtmlConf.type).toBe('header5')
    const html = header5ToHtmlConf.elemToHtml(elem, 'hello')
    expect(html).toBe('<h5>hello</h5>')
  })
})


================================================
FILE: packages/basic-modules/__tests__/header/helper.test.ts
================================================
/**
 * @description header helper test
 * @author wangfupeng
 */

import { Editor, Transforms } from 'slate'
import createEditor from '../../../../tests/utils/create-editor'
import { getHeaderType, isMenuDisabled, setHeaderType } from '../../src/modules/header/helper'

describe('header helper', () => {
  let editor: any
  let startLocation: any

  beforeEach(() => {
    editor = createEditor()
    startLocation = Editor.start(editor, [])
  })

  afterEach(() => {
    editor = null
    startLocation = null
  })

  it('get header type', () => {
    editor.select(startLocation)
    expect(getHeaderType(editor)).toBe('paragraph')

    Transforms.setNodes(editor, { type: 'header1' })
    expect(getHeaderType(editor)).toBe('header1')
  })

  it('is menu disabled', () => {
    editor.select(startLocation)
    expect(isMenuDisabled(editor)).toBeFalsy()

    Transforms.setNodes(editor, { type: 'header1' })
    expect(isMenuDisabled(editor)).toBeFalsy()

    editor.insertNode({ type: 'pre', children: [{ type: 'code', children: [{ text: 'var' }] }] })
    expect(isMenuDisabled(editor)).toBeTruthy() // 只能用于 p header
    // Transforms.removeNodes(editor, { mode: 'highest' }) // 移除 pre/code
  })

  it('set header type', () => {
    editor.select(startLocation)
    setHeaderType(editor, 'header1')

    const headers = editor.getElemsByTypePrefix('header1')
    expect(headers.length).toBe(1)
  })
})


================================================
FILE: packages/basic-modules/__tests__/header/menu/header-select-menu.test.ts
================================================
/**
 * @description header select menu test
 * @author wangfupeng
 */

import { Editor, Transforms } from 'slate'
import createEditor from '../../../../../tests/utils/create-editor'
import HeaderSelectMenu from '../../../src/modules/header/menu/HeaderSelectMenu'

describe('header select menu', () => {
  const editor = createEditor()
  const startLocation = Editor.start(editor, [])
  const menu = new HeaderSelectMenu()

  it('get options', () => {
    editor.select(startLocation)
    const options1 = menu.getOptions(editor)
    const selectedP = options1.some(opt => opt.selected && opt.value === 'paragraph') // 选中“文本”
    expect(selectedP).toBeTruthy()

    Transforms.setNodes(editor, { type: 'header1' })
    const options2 = menu.getOptions(editor)
    const selectedHeader = options2.some(opt => opt.selected && opt.value === 'header1') // 选中“h1”
    expect(selectedHeader).toBeTruthy()
  })

  // isActive 无逻辑,不用测试

  // getValue isDisabled exec 已经在 helper.test.ts 中测试过了
})


================================================
FILE: packages/basic-modules/__tests__/header/menu/header1-menu.test.ts
================================================
/**
 * @description header1 menu test
 * @author wangfupeng
 */

import { Editor } from 'slate'
import createEditor from '../../../../../tests/utils/create-editor'
import Header1ButtonMenu from '../../../src/modules/header/menu/Header1ButtonMenu'
import Header2ButtonMenu from '../../../src/modules/header/menu/Header2ButtonMenu'
import Header3ButtonMenu from '../../../src/modules/header/menu/Header3ButtonMenu'
import Header4ButtonMenu from '../../../src/modules/header/menu/Header4ButtonMenu'
import Header5ButtonMenu from '../../../src/modules/header/menu/Header5ButtonMenu'

describe('header menu', () => {
  const editor = createEditor()
  const startLocation = Editor.start(editor, [])

  describe('header1 menu', () => {
    const menu = new Header1ButtonMenu()

    it('exec', () => {
      editor.select(startLocation)

      menu.exec(editor, 'paragraph') // 设置 header ( paragraph 是当前选中的 node type )
      const headers1 = editor.getElemsByTypePrefix('header1')
      expect(headers1.length).toBe(1)

      menu.exec(editor, 'header1') // 取消 header( header1 是当前选中的 node type )
      const headers2 = editor.getElemsByTypePrefix('header1')
      expect(headers2.length).toBe(0)
    })
  })

  describe('header2 menu', () => {
    const menu = new Header2ButtonMenu()

    it('exec', () => {
      editor.select(startLocation)

      menu.exec(editor, 'paragraph') // 设置 header ( paragraph 是当前选中的 node type )
      const headers1 = editor.getElemsByTypePrefix('header2')
      expect(headers1.length).toBe(1)

      menu.exec(editor, 'header2') // 取消 header( header2 是当前选中的 node type )
      const headers2 = editor.getElemsByTypePrefix('header2')
      expect(headers2.length).toBe(0)
    })
  })

  describe('header3 menu', () => {
    const menu = new Header3ButtonMenu()

    it('exec', () => {
      editor.select(startLocation)

      menu.exec(editor, 'paragraph') // 设置 header ( paragraph 是当前选中的 node type )
      const headers1 = editor.getElemsByTypePrefix('header3')
      expect(headers1.length).toBe(1)

      menu.exec(editor, 'header3') // 取消 header( header3 是当前选中的 node type )
      const headers2 = editor.getElemsByTypePrefix('header3')
      expect(headers2.length).toBe(0)
    })
  })

  describe('header4 menu', () => {
    const menu = new Header4ButtonMenu()

    it('exec', () => {
      editor.select(startLocation)

      menu.exec(editor, 'paragraph') // 设置 header ( paragraph 是当前选中的 node type )
      const headers1 = editor.getElemsByTypePrefix('header4')
      expect(headers1.length).toBe(1)

      menu.exec(editor, 'header4') // 取消 header( header4 是当前选中的 node type )
      const headers2 = editor.getElemsByTypePrefix('header4')
      expect(headers2.length).toBe(0)
    })
  })

  describe('header5 menu', () => {
    const menu = new Header5ButtonMenu()

    it('exec', () => {
      editor.select(startLocation)

      menu.exec(editor, 'paragraph') // 设置 header ( paragraph 是当前选中的 node type )
      const headers1 = editor.getElemsByTypePrefix('header5')
      expect(headers1.length).toBe(1)

      menu.exec(editor, 'header5') // 取消 header( header5 是当前选中的 node type )
      const headers2 = editor.getElemsByTypePrefix('header5')
      expect(headers2.length).toBe(0)
    })
  })
})


================================================
FILE: packages/basic-modules/__tests__/header/parse-html.test.ts
================================================
/**
 * @description parse html test
 * @author wangfupeng
 */

import { $ } from 'dom7'
import createEditor from '../../../../tests/utils/create-editor'
import { parseHeader1HtmlConf } from '../../src/modules/header/parse-elem-html'

describe('header - parse html', () => {
  const editor = createEditor()

  it('with children', () => {
    const $h1 = $(`<h1></h1>`)
    const children = [{ text: 'hello ' }, { text: 'world', bold: true }]

    // match selector
    expect($h1[0].matches(parseHeader1HtmlConf.selector)).toBeTruthy()

    // parse html
    const res = parseHeader1HtmlConf.parseElemHtml($h1[0], children, editor)
    expect(res).toEqual({
      type: `header1`,
      children: [{ text: 'hello ' }, { text: 'world', bold: true }],
    })
  })

  it('without children', () => {
    const $h1 = $(`<h1>hello world</h1>`)

    // match selector
    expect($h1[0].matches(parseHeader1HtmlConf.selector)).toBeTruthy()

    // parse html
    const res = parseHeader1HtmlConf.parseElemHtml($h1[0], [], editor)
    expect(res).toEqual({
      type: `header1`,
      children: [{ text: 'hello world' }],
    })
  })
})


================================================
FILE: packages/basic-modules/__tests__/header/plugin.test.ts
================================================
/**
 * @description header plugin test
 * @author wangfupeng
 */

import { Editor, Transforms } from 'slate'
import createEditor from '../../../../tests/utils/create-editor'
import withHeader from '../../src/modules/header/plugin'

describe('header plugin', () => {
  const editor = withHeader(createEditor())
  const startLocation = Editor.start(editor, [])

  it('header break', () => {
    editor.select(startLocation)

    Transforms.setNodes(editor, { type: 'header1' })
    editor.insertBreak() // 在 header 换行,会生成 p

    const paragraphs = editor.getElemsByTypePrefix('paragraph')
    expect(paragraphs.length).toBe(1)
  })
})


================================================
FILE: packages/basic-modules/__tests__/header/render-elem.test.ts
================================================
/**
 * @description header - render elem test
 * @author wangfupeng
 */

import createEditor from '../../../../tests/utils/create-editor'
import {
  renderHeader1Conf,
  renderHeader2Conf,
  renderHeader3Conf,
  renderHeader4Conf,
  renderHeader5Conf,
} from '../../src/modules/header/render-elem'

describe('render header elem', () => {
  const editor = createEditor()

  it('render h1', () => {
    expect(renderHeader1Conf.type).toBe('header1')

    const elem = { type: 'header1', children: [] }
    const vnode = renderHeader1Conf.renderElem(elem, null, editor)
    expect(vnode.sel).toBe('h1')
  })

  it('render h2', () => {
    expect(renderHeader2Conf.type).toBe('header2')

    const elem = { type: 'header2', children: [] }
    const vnode = renderHeader2Conf.renderElem(elem, null, editor)
    expect(vnode.sel).toBe('h2')
  })

  it('render h3', () => {
    expect(renderHeader3Conf.type).toBe('header3')

    const elem = { type: 'header3', children: [] }
    const vnode = renderHeader3Conf.renderElem(elem, null, editor)
    expect(vnode.sel).toBe('h3')
  })

  it('render h4', () => {
    expect(renderHeader4Conf.type).toBe('header4')

    const elem = { type: 'header4', children: [] }
    const vnode = renderHeader4Conf.renderElem(elem, null, editor)
    expect(vnode.sel).toBe('h4')
  })

  it('render h5', () => {
    expect(renderHeader5Conf.type).toBe('header5')

    const elem = { type: 'header5', children: [] }
    const vnode = renderHeader5Conf.renderElem(elem, null, editor)
    expect(vnode.sel).toBe('h5')
  })
})


================================================
FILE: packages/basic-modules/__tests__/image/elem-to-html.test.ts
================================================
/**
 * @description image - elem to html test
 * @author wangfupeng
 */

import { imageToHtmlConf } from '../../src/modules/image/elem-to-html'

describe('image to html', () => {
  it('to html', () => {
    expect(imageToHtmlConf.type).toBe('image')

    const src = 'https://www.wangeditor.com/imgs/logo.png'
    const href = 'https://www.wangeditor.com/'
    const elem = {
      type: 'image',
      src,
      alt: 'logo',
      href,
      style: { width: '100', height: '80' },
      children: [{ text: '' }], // void node 必须包含一个空 text
    }
    const html = imageToHtmlConf.elemToHtml(elem, '')

    expect(html).toBe(
      `<img src="${src}" alt="logo" data-href="${href}" style="width: 100;height: 80;"/>`
    )
  })
})


================================================
FILE: packages/basic-modules/__tests__/image/helper.test.ts
================================================
/**
 * @description image helper test
 * @author wangfupeng
 */

import { Editor, Transforms } from 'slate'
import { DomEditor } from '@wangeditor/core'
import createEditor from '../../../../tests/utils/create-editor'
import {
  insertImageNode,
  updateImageNode,
  isInsertImageMenuDisabled,
} from '../../src/modules/image/helper'

describe('image helper', () => {
  let editor: any
  let startLocation: any

  const src = 'https://www.wangeditor.com/imgs/logo.png'
  const alt = 'logo'
  const href = 'https://www.wangeditor.com/'

  beforeEach(() => {
    editor = createEditor()
    startLocation = Editor.start(editor, [])
  })

  afterEach(() => {
    editor = null
    startLocation = null
  })

  it('insert image node', async () => {
    editor.select(startLocation)
    await insertImageNode(editor, src, alt, href)
    const images = editor.getElemsByTypePrefix('image')
    expect(images.length).toBe(1)
  })

  it('update image node', async () => {
    editor.select(startLocation)

    const elem = {
      type: 'image',
      src,
      alt,
      href,
      style: { width: '100', height: '80' },
      children: [{ text: '' }], // void node 必须包含一个空 text
    }
    editor.insertNode(elem) // 插入图片
    editor.select({
      path: [0, 1, 0], // 选中图片
      offset: 0,
    })

    const newSrc = 'https://www.baidu.com/logo.png'
    const newAlt = 'baidu'
    const newHref = 'https://www.baidu.com/'
    await updateImageNode(editor, newSrc, newAlt, newHref, {}) // 更新图片信息

    const imageNode = DomEditor.getSelectedNodeByType(editor, 'image')
    expect(imageNode).not.toBeNull()
  })

  it('is menu disable', async () => {
    editor.deselect()
    expect(isInsertImageMenuDisabled(editor)).toBeTruthy()

    editor.select(startLocation)
    expect(isInsertImageMenuDisabled(editor)).toBeFalsy()

    editor.insertText('hello')
    editor.select([])
    expect(isInsertImageMenuDisabled(editor)).toBeTruthy()

    editor.select(startLocation)
    Transforms.setNodes(editor, { type: 'header1' })
    expect(isInsertImageMenuDisabled(editor)).toBeTruthy()
  })
})


================================================
FILE: packages/basic-modules/__tests__/image/menu/del-image.test.ts
================================================
/**
 * @description delete image menu test
 * @author wangfupeng
 */

import { Editor } from 'slate'
import createEditor from '../../../../../tests/utils/create-editor'
import DeleteImage from '../../../src/modules/image/menu/DeleteImage'

describe('delete image menu', () => {
  const menu = new DeleteImage()
  let editor: any
  let startLocation: any

  const src = 'https://www.wangeditor.com/imgs/logo.png'
  const alt = 'logo'
  const href = 'https://www.wangeditor.com/'

  beforeEach(() => {
    editor = createEditor()
    startLocation = Editor.start(editor, [])
  })

  afterEach(() => {
    editor = null
    startLocation = null
  })

  // getValue isActive 无逻辑,不用测试

  it('is disabled', () => {
    editor.deselect()
    expect(menu.isDisabled(editor)).toBeTruthy()

    editor.select(startLocation)
    expect(menu.isDisabled(editor)).toBeTruthy()

    const elem = {
      type: 'image',
      src,
      alt,
      href,
      children: [{ text: '' }], // void node 必须包含一个空 text
    }
    editor.insertNode(elem) // 插入图片
    editor.select({
      path: [0, 1, 0], // 选中图片
      offset: 0,
    })
    expect(menu.isDisabled(editor)).toBeFalsy()
  })

  it('exec', () => {
    editor.select(startLocation)
    const elem = {
      type: 'image',
      src,
      alt,
      href,
      children: [{ text: '' }], // void node 必须包含一个空 text
    }
    editor.insertNode(elem) // 插入图片
    editor.select({
      path: [0, 1, 0], // 选中图片
      offset: 0,
    })

    menu.exec(editor, '')
    const images = editor.getElemsByTypePrefix('image')
    expect(images.length).toBe(0)
  })
})


================================================
FILE: packages/basic-modules/__tests__/image/menu/edit-image.test.ts
================================================
/**
 * @description edit image menu test
 * @author wangfupeng
 */

import { Editor } from 'slate'
import createEditor from '../../../../../tests/utils/create-editor'
import EditImage from '../../../src/modules/image/menu/EditImage'

describe('edit image menu', () => {
  const menu = new EditImage()
  let editor: any
  let startLocation: any

  const src = 'https://www.wangeditor.com/imgs/logo.png'
  const alt = 'logo'
  const href = 'https://www.wangeditor.com/'

  beforeEach(() => {
    editor = createEditor()
    startLocation = Editor.start(editor, [])
  })

  afterEach(() => {
    editor = null
    startLocation = null
  })

  // getValue isActive exec 无逻辑,不用测试

  it('is disabled', () => {
    editor.deselect()
    expect(menu.isDisabled(editor)).toBeTruthy()

    editor.select(startLocation)
    expect(menu.isDisabled(editor)).toBeTruthy()

    const elem = {
      type: 'image',
      src,
      alt,
      href,
      style: { width: '100', height: '80' },
      children: [{ text: '' }], // void node 必须包含一个空 text
    }
    editor.insertNode(elem) // 插入图片
    editor.select({
      path: [0, 1, 0], // 选中图片
      offset: 0,
    })
    expect(menu.isDisabled(editor)).toBeFalsy()
  })

  it('get modal position node', () => {
    editor.select(startLocation)
    expect(menu.getModalPositionNode(editor)).toBeNull()

    const elem = {
      type: 'image',
      src,
      alt,
      href,
      style: { width: '100', height: '80' },
      children: [{ text: '' }], // void node 必须包含一个空 text
    }
    editor.insertNode(elem) // 插入图片
    editor.select({
      path: [0, 1, 0], // 选中图片
      offset: 0,
    })
    const imageNode = menu.getModalPositionNode(editor)
    expect((imageNode as any).src).toBe(src)
  })

  it('get modal content elem', () => {
    editor.select(startLocation)
    const imageElem = {
      type: 'image',
      src,
      alt,
      href,
      style: { width: '100', height: '80' },
      children: [{ text: '' }], // void node 必须包含一个空 text
    }
    editor.insertNode(imageElem) // 插入图片
    editor.select({
      path: [0, 1, 0], // 选中图片
      offset: 0,
    })

    const elem = menu.getModalContentElem(editor)
    expect(elem.tagName).toBe('DIV')

    // updateImage 在 helper.test.ts 中测试
  })
})


================================================
FILE: packages/basic-modules/__tests__/image/menu/insert-image.test.ts
================================================
/**
 * @description insert image menu test
 * @author wangfupeng
 */

import { Editor, Transforms } from 'slate'
import createEditor from '../../../../../tests/utils/create-editor'
import InsertImage from '../../../src/modules/image/menu/InsertImage'

describe('insert image menu', () => {
  const menu = new InsertImage()
  let editor: any
  let startLocation: any

  beforeEach(() => {
    editor = createEditor()
    startLocation = Editor.start(editor, [])
  })

  afterEach(() => {
    editor = null
    startLocation = null
  })

  // getValue isActive exec 无逻辑,不用测试

  it('is disabled', () => {
    editor.deselect()
    expect(menu.isDisabled(editor)).toBeTruthy()

    editor.select(startLocation)
    expect(menu.isDisabled(editor)).toBeFalsy()

    editor.insertText('xxx')
    editor.select([]) // 全选文字
    expect(menu.isDisabled(editor)).toBeTruthy() // 非折叠选区,则不可用

    editor.select(startLocation)
    Transforms.setNodes(editor, { type: 'header1' })
    expect(menu.isDisabled(editor)).toBeTruthy() // header 中不可用

    Transforms.setNodes(editor, { type: 'blockquote' })
    expect(menu.isDisabled(editor)).toBeTruthy() // blockquote 中不可用
  })

  // getModalPositionNode 无逻辑,不用测试

  it('get modal content elem', () => {
    const elem = menu.getModalContentElem(editor)
    expect(elem.tagName).toBe('DIV')

    // insertImage 在 helper.test.ts 中测试
  })
})


================================================
FILE: packages/basic-modules/__tests__/image/menu/view-image-link.test.ts
================================================
/**
 * @description view image link menu test
 * @author wangfupeng
 */

import { Editor } from 'slate'
import createEditor from '../../../../../tests/utils/create-editor'
import ViewImageLink from '../../../src/modules/image/menu/ViewImageLink'

describe('view image link menu', () => {
  const menu = new ViewImageLink()
  let editor: any
  let startLocation: any

  const src = 'https://www.wangeditor.com/imgs/logo.png'
  const alt = 'logo'
  const href = 'https://www.wangeditor.com/'

  beforeEach(() => {
    editor = createEditor()
    startLocation = Editor.start(editor, [])
  })

  afterEach(() => {
    editor = null
    startLocation = null
  })

  it('getValue and isDisabled', () => {
    editor.select(startLocation)
    expect(menu.getValue(editor)).toBe('')
    expect(menu.isDisabled(editor)).toBeTruthy()

    const elem = {
      type: 'image',
      src,
      alt,
      href,
      style: { width: '100', height: '80' },
      children: [{ text: '' }], // void node 必须包含一个空 text
    }
    editor.insertNode(elem) // 插入图片
    editor.select({
      path: [0, 1, 0], // 选中图片
      offset: 0,
    })
    expect(menu.getValue(editor)).toBe(href)
    expect(menu.isDisabled(editor)).toBeFalsy()
  })

  // isActive 无逻辑,不用测试

  // exec 逻辑简单,不用测试
})


================================================
FILE: packages/basic-modules/__tests__/image/menu/width-menus.test.ts
================================================
/**
 * @description image width menus test
 * @author wangfupeng
 */

import { Editor } from 'slate'
import createEditor from '../../../../../tests/utils/create-editor'
import Width30 from '../../../src/modules/image/menu/Width30'
import Width50 from '../../../src/modules/image/menu/Width50'
import Width100 from '../../../src/modules/image/menu/Width100'

describe('image width menus', () => {
  const width30Menu = new Width30()
  const width50Menu = new Width50()
  const width100Menu = new Width100()

  let editor: any
  let startLocation: any

  const src = 'https://www.wangeditor.com/imgs/logo.png'
  const alt = 'logo'
  const href = 'https://www.wangeditor.com/'

  beforeEach(() => {
    editor = createEditor()
    startLocation = Editor.start(editor, [])
  })

  afterEach(() => {
    editor = null
    startLocation = null
  })

  // getValue isActive 无逻辑,不用测试

  it('is disabled', () => {
    editor.deselect()
    expect(width30Menu.isDisabled(editor)).toBeTruthy()
    expect(width50Menu.isDisabled(editor)).toBeTruthy()
    expect(width100Menu.isDisabled(editor)).toBeTruthy()

    editor.select(startLocation)
    expect(width30Menu.isDisabled(editor)).toBeTruthy()
    expect(width50Menu.isDisabled(editor)).toBeTruthy()
    expect(width100Menu.isDisabled(editor)).toBeTruthy()

    const elem = {
      type: 'image',
      src,
      alt,
      href,
      style: { width: '100', height: '80' },
      children: [{ text: '' }], // void node 必须包含一个空 text
    }
    editor.insertNode(elem) // 插入图片
    editor.select({
      path: [0, 1, 0], // 选中图片
      offset: 0,
    })
    expect(width30Menu.isDisabled(editor)).toBeFalsy()
    expect(width50Menu.isDisabled(editor)).toBeFalsy()
    expect(width100Menu.isDisabled(editor)).toBeFalsy()
  })

  it('exec', () => {
    editor.select(startLocation)
    const elem = {
      type: 'image',
      src,
      alt,
      href,
      style: { width: '100', height: '80' },
      children: [{ text: '' }], // void node 必须包含一个空 text
    }
    editor.insertNode(elem) // 插入图片
    editor.select({
      path: [0, 1, 0], // 选中图片
      offset: 0,
    })

    width30Menu.exec(editor, '')
    const image1 = editor.getElemsByTypePrefix('image')[0]
    expect(image1.style.width).toBe('30%')
    expect(image1.style.height).toBe('')

    width50Menu.exec(editor, '')
    const image2 = editor.getElemsByTypePrefix('image')[0]
    expect(image2.style.width).toBe('50%')
    expect(image2.style.height).toBe('')

    width100Menu.exec(editor, '')
    const image3 = editor.getElemsByTypePrefix('image')[0]
    expect(image3.style.width).toBe('100%')
    expect(image3.style.height).toBe('')
  })
})


================================================
FILE: packages/basic-modules/__tests__/image/parse-html.test.ts
================================================
/**
 * @description parse html test
 * @author wangfupeng
 */

import { $ } from 'dom7'
import createEditor from '../../../../tests/utils/create-editor'
import { parseHtmlConf } from '../../src/modules/image/parse-elem-html'

describe('image - parse html', () => {
  const editor = createEditor()

  it('parse html', () => {
    const $img = $(
      '<img src="hello.png" alt="hello" data-href="http://localhost/" style="width: 10px; height: 5px;"/>'
    )

    // match selector
    expect($img[0].matches(parseHtmlConf.selector)).toBeTruthy()

    // parse
    const res = parseHtmlConf.parseElemHtml($img[0], [], editor)
    expect(res).toEqual({
      type: 'image',
      src: 'hello.png',
      alt: 'hello',
      href: 'http://localhost/',
      style: {
        width: '10px',
        height: '5px',
      },
      children: [{ text: '' }],
    })
  })
})


================================================
FILE: packages/basic-modules/__tests__/image/plugin.test.ts
================================================
/**
 * @description image plugin test
 * @author wangfupeng
 */

import createEditor from '../../../../tests/utils/create-editor'
import withImage from '../../src/modules/image/plugin'

describe('image plugin', () => {
  const editor = withImage(createEditor())
  const elem = { type: 'image', children: [{ text: '' }] }

  it('image is inline', () => {
    expect(editor.isInline(elem)).toBeTruthy()
  })

  it('image is void', () => {
    expect(editor.isVoid(elem)).toBeTruthy()
  })
})


================================================
FILE: packages/basic-modules/__tests__/image/render-elem.test.ts
================================================
/**
 * @description image - render elem test
 * @author wangfupeng
 */

import { Editor } from 'slate'
import { renderImageConf } from '../../src/modules/image/render-elem'
import createEditor from '../../../../tests/utils/create-editor'

describe('image render elem', () => {
  let editor: any
  let startLocation: any

  beforeEach(() => {
    editor = createEditor()
    startLocation = Editor.start(editor, [])
  })

  afterEach(() => {
    editor.clear()
    editor.destroy()
    editor = null
    startLocation = null
  })

  it('render image - unselected image', () => {
    expect(renderImageConf.type).toBe('image')

    const src = 'https://www.wangeditor.com/imgs/logo.png'
    const href = 'https://www.wangeditor.com/'
    const elem = {
      type: 'image',
      src,
      alt: 'logo',
      href,
      style: { width: '100', height: '80' },
      children: [{ text: '' }], // void node 必须包含一个空 text
    }

    const containerVnode = renderImageConf.renderElem(elem, null, editor) as any
    expect(containerVnode.sel).toBe('div')
    expect(containerVnode.data.className).toBe('w-e-image-container')
    expect(containerVnode.data.style.width).toBe('100')
    expect(containerVnode.data.style.height).toBe('80')

    const imageVnode = containerVnode.children[0] as any
    expect(imageVnode.sel).toBe('img')
    expect(imageVnode.data.src).toBe(src)
    expect(imageVnode.data['data-href']).toBe(href)
  })

  it('render image - selected image', () => {
    const src = 'https://www.wangeditor.com/imgs/logo.png'
    const href = 'https://www.wangeditor.com/'
    const elem = {
      type: 'image',
      src,
      alt: 'logo',
      href,
      style: { width: '100', height: '80' },
      children: [{ text: '' }], // void node 必须包含一个空 text
    }

    editor.select(startLocation)
    editor.insertNode(elem) // 插入图片
    editor.select({
      path: [0, 1, 0], // 选中图片
      offset: 0,
    })

    const containerVnode = renderImageConf.renderElem(elem, null, editor) as any
    expect(containerVnode.sel).toBe('div')
    expect(containerVnode.data.className.indexOf('w-e-selected-image-container')).toBeGreaterThan(0)
    expect(containerVnode.children.length).toBe(5) // image + 4 个拖拽触手
  })
})


================================================
FILE: packages/basic-modules/__tests__/indent/menu/decrease-indent-menu.test.ts
================================================
/**
 * @description decrease indent menu test
 * @author wangfupeng
 */

import { Editor, Transforms } from 'slate'
import createEditor from '../../../../../tests/utils/create-editor'
import DecreaseIndentMenu from '../../../src/modules/indent/menu/DecreaseIndentMenu'

describe('decrease indent menu', () => {
  let editor: any
  let startLocation: any

  const menu = new DecreaseIndentMenu()

  beforeEach(() => {
    editor = createEditor()
    startLocation = Editor.start(editor, [])
  })

  afterEach(() => {
    editor = null
    startLocation = null
  })

  it('is disabled', () => {
    editor.select(startLocation)
    expect(menu.isDisabled(editor)).toBeTruthy() // 没有 indent 则 disabled

    Transforms.setNodes(editor, { type: 'header1', children: [] })
    expect(menu.isDisabled(editor)).toBeTruthy() // 没有 indent 则 disabled

    editor.insertNode({ type: 'pre', children: [{ type: 'code', children: [{ text: 'var' }] }] })
    expect(menu.isDisabled(editor)).toBeTruthy() // 除了 p header 之外,其他 type 不可用 indent
    // Transforms.removeNodes(editor, { mode: 'highest' }) // 移除 pre/code
  })

  // isActive 不用测试

  // getValue 在 increase menu 已测试过

  it('exec', () => {
    editor.select(startLocation)
    Transforms.setNodes(editor, { type: 'paragraph', indent: '2em', children: [] })

    expect(menu.isDisabled(editor)).toBeFalsy() // 有 indent 则取消 disabled

    menu.exec(editor, '')
    expect(menu.getValue(editor)).toBe('')
  })
})


================================================
FILE: packages/basic-modules/__tests__/indent/menu/increase-indent-menu.test.ts
================================================
/**
 * @description increase indent menu test
 * @author wangfupeng
 */

import { Editor, Transforms } from 'slate'
import createEditor from '../../../../../tests/utils/create-editor'
import IncreaseIndentMenu from '../../../src/modules/indent/menu/IncreaseIndentMenu'

describe('increase indent menu', () => {
  let editor: any
  let startLocation: any

  const menu = new IncreaseIndentMenu()

  beforeEach(() => {
    editor = createEditor()
    startLocation = Editor.start(editor, [])
  })

  afterEach(() => {
    editor = null
    startLocation = null
  })

  it('is disabled', () => {
    editor.select(startLocation)
    expect(menu.isDisabled(editor)).toBeFalsy()

    Transforms.setNodes(editor, { type: 'header1', children: [] })
    expect(menu.isDisabled(editor)).toBeFalsy()

    editor.insertNode({ type: 'pre', children: [{ type: 'code', children: [{ text: 'var' }] }] })
    expect(menu.isDisabled(editor)).toBeTruthy() // 除了 p header 之外,其他 type 不可用 indent
    // Transforms.removeNodes(editor, { mode: 'highest' }) // 移除 pre/code
  })

  // isActive 不用测试

  it('exec and getValue', () => {
    editor.select(startLocation)
    expect(menu.getValue(editor)).toBe('')

    menu.exec(editor, '')
    expect(menu.getValue(editor)).toBe('2em')
  })

  it('indent value', () => {
    editor.insertNode({
      type: 'paragraph',
      children: [{ fontSize: '18px', text: 'text1' } as any],
    })

    menu.exec(editor, '')

    expect(menu.getValue(editor)).toBe('36px')
  })
})


================================================
FILE: packages/basic-modules/__tests__/indent/parse-html.test.ts
================================================
/**
 * @description parse html test
 * @author wangfupeng
 */

import { $ } from 'dom7'
import createEditor from '../../../../tests/utils/create-editor'
import { parseStyleHtml } from '../../src/modules/indent/parse-style-html'
import { preParseHtmlConf } from '../../src/modules/indent/pre-parse-html'

describe('indent - parse style', () => {
  const editor = createEditor()

  it('parse style', () => {
    const $p = $('<p style="text-indent: 2em;"></p>')
    const paragraph = { type: 'paragraph', children: [{ text: 'hello' }] }

    // parse
    const res = parseStyleHtml($p[0], paragraph, editor)
    expect(res).toEqual({
      type: 'paragraph',
      indent: '2em',
      children: [{ text: 'hello' }],
    })
  })
})

describe('indent - pre parse html', () => {
  it('pre parse', () => {
    expect(preParseHtmlConf.selector).toBe('p,h1,h2,h3,h4,h5')

    const $p = $('<p style="padding-left: 2em;"></p>')

    // parse
    const res = preParseHtmlConf.preParseHtml($p[0])
    expect((res as HTMLParagraphElement).style.textIndent).toBe('2em')
  })

  it('pre parse with px unit', () => {
    expect(preParseHtmlConf.selector).toBe('p,h1,h2,h3,h4,h5')

    const $p = $('<p style="padding-left: 32px;"></p>')

    // parse
    const res = preParseHtmlConf.preParseHtml($p[0])
    expect((res as HTMLParagraphElement).style.textIndent).toBe('2em')
  })
})


================================================
FILE: packages/basic-modules/__tests__/indent/render-text-style.test.tsx
================================================
/**
 * @description indent - render text style
 * @author wangfupeng
 */

import { jsx } from 'snabbdom'
import { renderStyle } from '../../src/modules/indent/render-style'

describe('indent - render text style', () => {
  it('render text style', () => {
    const indent = '2em'
    const elem = { type: 'paragraph', indent, children: [] }
    const vnode = <p>hello</p>

    // @ts-ignore
    const newVnode = renderStyle(elem, vnode)
    // @ts-ignore
    expect(newVnode.data.style.textIndent).toBe(indent)
  })
})


================================================
FILE: packages/basic-modules/__tests__/indent/text-style-to-html.test.ts
================================================
/**
 * @description indent - text style to html test
 * @author wangfupeng
 */

import { styleToHtml } from '../../src/modules/indent/style-to-html'

describe('indent - text style to html', () => {
  it('text style to html', () => {
    const indent = '2em'
    const elem = { type: 'paragraph', indent, children: [] }
    const html = styleToHtml(elem, '<p>hello</p>')
    expect(html).toBe(`<p style="text-indent: ${indent};">hello</p>`)
  })
})


================================================
FILE: packages/basic-modules/__tests__/justify/menus.test.ts
================================================
/**
 * @description justify menus test
 * @author wangfupeng
 */

import { Editor, Transforms } from 'slate'
import createEditor from '../../../../tests/utils/create-editor'
import JustifyCenterMenu from '../../src/modules/justify/menu/JustifyCenterMenu'
import JustifyJustifyMenu from '../../src/modules/justify/menu/JustifyJustifyMenu'
import JustifyLeftMenu from '../../src/modules/justify/menu/JustifyLeftMenu'
import JustifyRightMenu from '../../src/modules/justify/menu/JustifyRightMenu'

describe('justify menus', () => {
  let editor: any
  let startLocation: any

  const centerMenu = new JustifyCenterMenu()
  const justifyMenu = new JustifyJustifyMenu()
  const leftMenu = new JustifyLeftMenu()
  const rightMenu = new JustifyRightMenu()

  beforeEach(() => {
    editor = createEditor()
    startLocation = Editor.start(editor, [])
  })

  afterEach(() => {
    editor = null
    startLocation = null
  })

  // getValue getActive 不需要测试

  it('is disabled', () => {
    editor.deselect()
    expect(centerMenu.isDisabled(editor)).toBeTruthy()

    editor.select(startLocation)
    expect(centerMenu.isDisabled(editor)).toBeFalsy()

    editor.insertNode({ type: 'pre', children: [{ type: 'code', children: [{ text: 'var' }] }] })
    expect(centerMenu.isDisabled(editor)).toBeTruthy()
    // Transforms.removeNodes(editor, { mode: 'highest' }) // 移除 pre/code
  })

  it('exec', () => {
    editor.select(startLocation)

    centerMenu.exec(editor, '')
    const p1 = editor.getElemsByTypePrefix('paragraph')[0]
    expect(p1.textAlign).toBe('center')

    justifyMenu.exec(editor, '')
    const p2 = editor.getElemsByTypePrefix('paragraph')[0]
    expect(p2.textAlign).toBe('justify')

    leftMenu.exec(editor, '')
    const p3 = editor.getElemsByTypePrefix('paragraph')[0]
    expect(p3.textAlign).toBe('left')

    rightMenu.exec(editor, '')
    const p4 = editor.getElemsByTypePrefix('paragraph')[0]
    expect(p4.textAlign).toBe('right')
  })
})


================================================
FILE: packages/basic-modules/__tests__/justify/parse-html.test.ts
================================================
/**
 * @description parse html test
 * @author wangfupeng
 */

import { $ } from 'dom7'
import createEditor from '../../../../tests/utils/create-editor'
import { parseStyleHtml } from '../../src/modules/justify/parse-style-html'

describe('text align - parse style', () => {
  const editor = createEditor()

  it('parse style', () => {
    const $p = $('<p style="text-align: center;"></p>')
    const paragraph = { type: 'paragraph', children: [{ text: 'hello' }] }

    // parse
    const res = parseStyleHtml($p[0], paragraph, editor)
    expect(res).toEqual({
      type: 'paragraph',
      textAlign: 'center',
      children: [{ text: 'hello' }],
    })
  })
})


================================================
FILE: packages/basic-modules/__tests__/justify/render-text-style.test.tsx
================================================
/**
 * @description justify - render text style test
 * @author wangfupeng
 */

import { jsx } from 'snabbdom'
import { renderStyle } from '../../src/modules/justify/render-style'

describe('justify - render text style', () => {
  it('render text style', () => {
    const elem = { type: 'paragraph', textAlign: 'center', children: [] }
    const vnode = <span>hello</span>
    // @ts-ignore 忽略 vnode 格式
    const newVnode = renderStyle(elem, vnode)
    // @ts-ignore 忽略 vnode 格式
    expect(newVnode.data.style?.textAlign).toBe('center')
  })
})


================================================
FILE: packages/basic-modules/__tests__/justify/text-style-to-html.test.ts
================================================
/**
 * @description justify - text style to html test
 * @author wangfupeng
 */

import { styleToHtml } from '../../src/modules/justify/style-to-html'

describe('justify text-style-to-html', () => {
  it('text style to html', () => {
    const elem = { type: 'paragraph', textAlign: 'center', children: [] }
    const html = styleToHtml(elem, '<span>hello</span>')
    expect(html).toBe('<span style="text-align: center;">hello</span>')
  })
})


================================================
FILE: packages/basic-modules/__tests__/line-height/line-height-menu.test.ts
================================================
/**
 * @description line-height menu test
 * @author wangfupeng
 */

import { Editor, Transforms } from 'slate'
import createEditor from '../../../../tests/utils/create-editor'
import LineHeightMenu from '../../src/modules/line-height/menu/LineHeightMenu'

describe('line-height menu', () => {
  let editor: any
  let startLocation: any
  const menu = new LineHeightMenu()

  beforeEach(() => {
    editor = createEditor()
    startLocation = Editor.start(editor, [])
  })

  afterEach(() => {
    editor = null
    startLocation = null
  })

  it('get options', () => {
    editor.select(startLocation)

    const options = menu.getOptions(editor)
    expect(options.length).toBeGreaterThan(0)

    // 默认选中 空
    const selectedEmptyOne = options.some(opt => opt.value === '' && opt.selected)
    expect(selectedEmptyOne).toBe(true)
  })

  // isActive 返回 false ,不用测试

  it('get value', () => {
    editor.select(startLocation)
    expect(menu.getValue(editor)).toBe('')

    // 设置 lineHeight
    Transforms.setNodes(editor, { lineHeight: '1.5' }, { mode: 'highest' })
    expect(menu.getValue(editor)).toBe('1.5')
  })

  it('is disable', () => {
    editor.deselect()
    expect(menu.isDisabled(editor)).toBeTruthy()

    editor.select(startLocation)
    expect(menu.isDisabled(editor)).toBeFalsy()

    Transforms.setNodes(editor, { type: 'header1' })
    expect(menu.isDisabled(editor)).toBeFalsy()
    Transforms.setNodes(editor, { type: 'blockquote' })
    expect(menu.isDisabled(editor)).toBeFalsy()
    Transforms.setNodes(editor, { type: 'list-item' })
    expect(menu.isDisabled(editor)).toBeFalsy()

    editor.insertNode({ type: 'pre', children: [{ type: 'code', children: [{ text: 'var' }] }] })
    expect(menu.isDisabled(editor)).toBeTruthy()
    // Transforms.removeNodes(editor, { mode: 'highest' }) // 移除 pre/code
  })

  it('exec', () => {
    editor.select(startLocation)
    menu.exec(editor, '1.5')
    expect(menu.getValue(editor)).toBe('1.5')
  })
})


================================================
FILE: packages/basic-modules/__tests__/line-height/parse-html.test.ts
================================================
/**
 * @description parse html test
 * @author wangfupeng
 */

import { $ } from 'dom7'
import createEditor from '../../../../tests/utils/create-editor'
import { parseStyleHtml } from '../../src/modules/line-height/parse-style-html'

describe('line height - parse style', () => {
  const editor = createEditor()

  it('parse style', () => {
    const $p = $('<p style="line-height: 2.5;"></p>')
    const paragraph = { type: 'paragraph', children: [{ text: 'hello' }] }

    // parse
    const res = parseStyleHtml($p[0], paragraph, editor)
    expect(res).toEqual({
      type: 'paragraph',
      lineHeight: '2.5',
      children: [{ text: 'hello' }],
    })
  })
})


================================================
FILE: packages/basic-modules/__tests__/line-height/render-text-style.test.tsx
================================================
/**
 * @description line-height render text style test
 * @author wangfupeng
 */

import { jsx } from 'snabbdom'
import { renderStyle } from '../../src/modules/line-height/render-style'

describe('line-height render-text-style', () => {
  it('render text style', () => {
    const elem = { type: 'paragraph', lineHeight: '1.5', children: [] }
    const vnode = <span>hello</span>
    // @ts-ignore 忽略 vnode 格式检查
    const newVnode = renderStyle(elem, vnode)
    // @ts-ignore 忽略 vnode 格式检查
    expect(newVnode.data.style.lineHeight).toBe('1.5')
  })
})


================================================
FILE: packages/basic-modules/__tests__/line-height/text-style-to-html.test.ts
================================================
/**
 * @description line-height text-style-to-html test
 * @author wangfupeng
 */

import { styleToHtml } from '../../src/modules/line-height/style-to-html'

describe('line-height text-style-to-html', () => {
  it('text style to html', () => {
    const elem = { type: 'paragraph', lineHeight: '1.5', children: [] }
    const html = styleToHtml(elem, '<span>hello</span>')
    expect(html).toBe('<span style="line-height: 1.5;">hello</span>')
  })
})


================================================
FILE: packages/basic-modules/__tests__/link/elem-to-html.test.ts
================================================
/**
 * @description link - elem to html test
 * @author wangfupeng
 */

import { linkToHtmlConf } from '../../src/modules/link/elem-to-html'

describe('link elem to html', () => {
  it('link to html', () => {
    expect(linkToHtmlConf.type).toBe('link')

    const url = 'https://www.wangeditor.com/'
    const target = '_blank'
    const elem = { type: 'link', url, target, children: [] }

    const html = linkToHtmlConf.elemToHtml(elem, 'hello')
    expect(html).toBe(`<a href="${url}" target="${target}">hello</a>`)
  })
})


================================================
FILE: packages/basic-modules/__tests__/link/helper.test.ts
================================================
/**
 * @description link module helper test
 * @author wangfupeng
 */

import { Editor, Transforms } from 'slate'
import createEditor from '../../../../tests/utils/create-editor'
import { isMenuDisabled, insertLink, updateLink } from '../../src/modules/link/helper'

describe('link module helper', () => {
  let editor: any
  let startLocation: any

  beforeEach(() => {
    editor = createEditor()
    startLocation = Editor.start(editor, [])
  })

  afterEach(() => {
    editor = null
    startLocation = null
  })

  it('menu disable', () => {
    editor.deselect()
    expect(isMenuDisabled(editor)).toBeTruthy()

    editor.select(startLocation)
    expect(isMenuDisabled(editor)).toBeFalsy()

    editor.insertNode({
      type: 'link',
      url: 'https://www.wangeditor.com/',
      children: [{ text: 'xxx' }],
    })
    expect(isMenuDisabled(editor)).toBeTruthy() // 选中 link ,则禁用

    editor.clear()
    editor.insertNode({
      type: 'pre',
      children: [
        {
          type: 'code',
          children: [{ text: 'var' }],
        },
      ],
    })
    expect(isMenuDisabled(editor)).toBeTruthy() // 选中 code-block ,则禁用
  })

  it('insert link with collapsed selection', async () => {
    editor.select(startLocation)

    const url = 'https://www.wangeditor.com/'
    await insertLink(editor, 'hello', url)

    const links = editor.getElemsByTypePrefix('link')
    expect(links.length).toBe(1)
    const linkElem = links[0]
    expect(linkElem.url).toBe(url)
  })

  it('insert link with expand selection', async () => {
    editor.select(startLocation)
    editor.insertText('hello')
    Transforms.move(editor, {
      distance: 3, // 选中 3 个字母
      unit: 'character',
    })
    editor.select([]) // 全选

    const url = 'https://www.wangeditor.com/'
    await insertLink(editor, 'hello', url)

    const links = editor.getElemsByTypePrefix('link')
    expect(links.length).toBe(1)
    const linkElem = links[0]
    expect(linkElem.url).toBe(url)
  })

  it('update link', async () => {
    editor.select(startLocation)

    const url = 'https://www.wangeditor.com/'
    await insertLink(editor, 'hello', url)

    // 选区移动到 link 内部
    editor.select({
      path: [0, 1, 0],
      offset: 3,
    })

    // 更新链接
    const newUrl = 'https://www.wangeditor.com/123'
    await updateLink(editor, '', newUrl)

    const links = editor.getElemsByTypePrefix('link')
    expect(links.length).toBe(1)
    const linkElem = links[0]
    expect(linkElem.url).toBe(newUrl)
  })
})


================================================
FILE: packages/basic-modules/__tests__/link/menu/edit-link-menu.test.ts
================================================
/**
 * @description edit link menu test
 * @author wangfupeng
 */

import { Editor } from 'slate'
import createEditor from '../../../../../tests/utils/create-editor'
import EditLink from '../../../src/modules/link/menu/EditLink'

describe('edit link menu', () => {
  let editor: any
  let startLocation: any
  const menu = new EditLink()

  const linkNode = {
    type: 'link',
    url: 'https://www.wangeditor.com/',
    children: [{ text: 'xxx' }],
  }

  beforeEach(() => {
    editor = createEditor()
    startLocation = Editor.start(editor, [])
  })

  afterEach(() => {
    editor = null
    startLocation = null
  })

  it('get value', () => {
    editor.select(startLocation)
    expect(menu.getValue(editor)).toBe('')

    editor.insertNode(linkNode)
    editor.select({
      path: [0, 1, 0], // 选区定位到 link 内部
      offset: 1,
    })
    expect(menu.getValue(editor)).toBe(linkNode.url)
  })

  it('is active', () => {
    expect(menu.isActive(editor)).toBeFalsy()
  })

  it('is disable', () => {
    editor.select(startLocation)
    expect(menu.isDisabled(editor)).toBeTruthy()

    editor.insertNode(linkNode)
    editor.select({
      path: [0, 1, 0], // 选区定位到 link 内部
      offset: 1,
    })
    expect(menu.isDisabled(editor)).toBeFalsy()
  })

  it('get modal position node', () => {
    editor.select(startLocation)
    expect(menu.getModalPositionNode(editor)).toBeNull()

    editor.insertNode(linkNode)
    editor.select({
      path: [0, 1, 0], // 选区定位到 link 内部
      offset: 1,
    })
    const node = menu.getModalPositionNode(editor) as any
    expect(node.type).toBe('link')
    expect(node.url).toBe(linkNode.url)
  })

  it('get modal content elem', () => {
    editor.select(startLocation)
    const elem = menu.getModalContentElem(editor)
    expect(elem.tagName).toBe('DIV')
  })
})


================================================
FILE: packages/basic-modules/__tests__/link/menu/insert-link-menu.test.ts
================================================
/**
 * @description insert link menu test
 * @author wangfupeng
 */

import { Editor } from 'slate'
import createEditor from '../../../../../tests/utils/create-editor'
import InsertLinkMenu from '../../../src/modules/link/menu/InsertLink'

describe('insert link menu', () => {
  const editor = createEditor()
  const menu = new InsertLinkMenu()
  const startLocation = Editor.start(editor, [])

  afterEach(() => {
    editor.select(startLocation)
    editor.clear()
    editor.deselect()
  })

  it('get value', () => {
    expect(menu.getValue(editor)).toBe('')
  })

  it('is active', () => {
    expect(menu.isActive(editor)).toBeFalsy()
  })

  it('get modal position node', () => {
    expect(menu.getModalPositionNode(editor)).toBeNull()
  })

  it('is disable', () => {
    editor.select(startLocation)
    expect(menu.isDisabled(editor)).toBeFalsy()
  })

  it('get modal content elem', () => {
    const elem = menu.getModalContentElem(editor)
    expect(elem.tagName).toBe('DIV')
  })
})


================================================
FILE: packages/basic-modules/__tests__/link/menu/unlink-menu.test.ts
================================================
/**
 * @description unlink menu test
 * @author wangfupeng
 */

import { Editor } from 'slate'
import createEditor from '../../../../../tests/utils/create-editor'
import UnLink from '../../../src/modules/link/menu/UnLink'

describe('unlink menu test', () => {
  let editor: any
  let startLocation: any
  const menu = new UnLink()

  const linkNode = {
    type: 'link',
    url: 'https://www.wangeditor.com/',
    children: [{ text: 'xxx' }],
  }

  beforeEach(() => {
    editor = createEditor()
    startLocation = Editor.start(editor, [])
  })

  afterEach(() => {
    editor = null
    startLocation = null
  })

  it('get value', () => {
    expect(menu.getValue(editor)).toBe('')
  })

  it('is active', () => {
    expect(menu.isActive(editor)).toBe(false)
  })

  it('is disable', () => {
    editor.select(startLocation)
    expect(menu.isDisabled(editor)).toBeTruthy()

    editor.insertNode(linkNode)
    editor.select({
      path: [0, 1, 0], // 选区定位到 link 内部
      offset: 1,
    })
    expect(menu.isDisabled(editor)).toBeFalsy()
  })

  it('exec', () => {
    editor.select(startLocation)
    editor.insertNode(linkNode)
    editor.select({
      path: [0, 1, 0], // 选区定位到 link 内部
      offset: 1,
    })

    menu.exec(editor, '')
    const links = editor.getElemsByTypePrefix('link')
    expect(links.length).toBe(0)
  })
})


================================================
FILE: packages/basic-modules/__tests__/link/menu/view-link-menu.test.ts
================================================
/**
 * @description view link menu test
 * @author wangfupeng
 */

import { Editor } from 'slate'
import createEditor from '../../../../../tests/utils/create-editor'
import ViewLink from '../../../src/modules/link/menu/ViewLink'

describe('view link menu', () => {
  let editor: any
  let startLocation: any
  const menu = new ViewLink()

  const linkNode = {
    type: 'link',
    url: 'https://www.wangeditor.com/',
    children: [{ text: 'xxx' }],
  }

  beforeEach(() => {
    editor = createEditor()
    startLocation = Editor.start(editor, [])
  })

  afterEach(() => {
    editor = null
    startLocation = null
  })

  it('get value', () => {
    editor.select(startLocation)
    expect(menu.getValue(editor)).toBe('')

    editor.insertNode(linkNode)
    editor.select({
      path: [0, 1, 0], // 选区定位到 link 内部
      offset: 1,
    })
    expect(menu.getValue(editor)).toBe(linkNode.url)
  })

  it('is active', () => {
    expect(menu.isActive(editor)).toBe(false)
  })

  it('is disable', () => {
    editor.select(startLocation)
    expect(menu.isDisabled(editor)).toBeTruthy()

    editor.insertNode(linkNode)
    editor.select({
      path: [0, 1, 0], // 选区定位到 link 内部
      offset: 1,
    })
    expect(menu.isDisabled(editor)).toBeFalsy()
  })
})


================================================
FILE: packages/basic-modules/__tests__/link/parse-html.test.ts
================================================
/**
 * @description parse html test
 * @author wangfupeng
 */

import { $ } from 'dom7'
import createEditor from '../../../../tests/utils/create-editor'
import { parseHtmlConf } from '../../src/modules/link/parse-elem-html'

describe('link - parse html', () => {
  const editor = createEditor()

  it('without children', () => {
    const $link = $('<a href="http://localhost/" target="_blank">hello world</a>')

    // match selector
    expect($link[0].matches(parseHtmlConf.selector)).toBeTruthy()

    // parse
    const res = parseHtmlConf.parseElemHtml($link[0], [], editor)
    expect(res).toEqual({
      type: 'link',
      url: 'http://localhost/',
      target: '_blank',
      children: [{ text: 'hello world' }],
    })
  })

  it('with children', () => {
    const $link = $('<a href="http://localhost/" target="_blank"></a>')
    const children = [{ text: 'hello ' }, { text: 'world', bold: true }]

    // match selector
    expect($link[0].matches(parseHtmlConf.selector)).toBeTruthy()

    // parse
    const res = parseHtmlConf.parseElemHtml($link[0], children, editor)
    expect(res).toEqual({
      type: 'link',
      url: 'http://localhost/',
      target: '_blank',
      children: [{ text: 'hello ' }, { text: 'world', bold: true }],
    })
  })
})


================================================
FILE: packages/basic-modules/__tests__/link/plugin.test.ts
================================================
/**
 * @description link plugin test
 * @author wangfupeng
 */

import { Editor } from 'slate'
import withLink from '../../src/modules/link/plugin'
import createEditor from '../../../../tests/utils/create-editor'

// 模拟 DataTransfer
class MyDataTransfer {
  private values: object = {}
  setData(type: string, value: string) {
    this.values[type] = value
  }
  getData(type: string): string {
    return this.values[type]
  }
}

describe('link plugin', () => {
  const editor = withLink(createEditor())
  const startLocation = Editor.start(editor, [])

  it('link is inline elem', () => {
    const elem = { type: 'link', children: [] }
    expect(editor.isInline(elem)).toBeTruthy()
  })

  it('link insert data', done => {
    const url = 'https://www.wangeditor.com/'

    const data = new MyDataTransfer()
    data.setData('text/plain', url)

    editor.select(startLocation)
    // @ts-ignore
    editor.insertData(data)

    setTimeout(() => {
      const links = editor.getElemsByTypePrefix('link')
      expect(links.length).toBe(1)
      const linkElem = links[0] as any
      expect(linkElem.url).toBe(url)
      done()
    })
  })
})


================================================
FILE: packages/basic-modules/__tests__/link/render-elem.test.ts
================================================
/**
 * @description link - render elem test
 * @author wangfupeng
 */

import createEditor from '../../../../tests/utils/create-editor'
import { renderLinkConf } from '../../src/modules/link/render-elem'

describe('link render elem', () => {
  const editor = createEditor()

  it('render elem', () => {
    expect(renderLinkConf.type).toBe('link')

    const url = 'https://www.wangeditor.com/'
    const target = '_blank'
    const elem = { type: 'link', url, target, children: [] }

    const vnode = renderLinkConf.renderElem(elem, null, editor) as any
    expect(vnode.sel).toBe('a')
    expect(vnode.data.href).toBe(url)
    expect(vnode.data.target).toBe(target)
  })
})


================================================
FILE: packages/basic-modules/__tests__/paragraph/elem-to-html.test.ts
================================================
import { html } from 'dom7'
/**
 * @description paragraph - elem to html test
 * @author wangfupeng
 */

import { pToHtmlConf } from '../../src/modules/paragraph/elem-to-html'

describe('paragraph - elem to html', () => {
  it('paragraph to html', () => {
    expect(pToHtmlConf.type).toBe('paragraph')

    const elem = { type: 'paragraph', children: [] }
    const html = pToHtmlConf.elemToHtml(elem, 'hello')
    expect(html).toBe('<p>hello</p>')
  })

  it('paragraph to html with empty children', () => {
    expect(pToHtmlConf.type).toBe('paragraph')

    const elem = { type: 'paragraph', children: [] }
    const html = pToHtmlConf.elemToHtml(elem, '')
    expect(html).toBe('<p><br></p>')
  })
})


================================================
FILE: packages/basic-modules/__tests__/paragraph/parse-html.test.ts
================================================
/**
 * @description parse html test
 * @author wangfupeng
 */

import { $ } from 'dom7'
import createEditor from '../../../../tests/utils/create-editor'
import { parseParagraphHtmlConf } from '../../src/modules/paragraph/parse-elem-html'

describe('paragraph - parse html', () => {
  const editor = createEditor()

  it('without children', () => {
    const $elem = $('<p>hello&nbsp;world</p>')

    // match selector
    expect($elem[0].matches(parseParagraphHtmlConf.selector)).toBeTruthy()

    // parse
    const res = parseParagraphHtmlConf.parseElemHtml($elem[0], [], editor)
    expect(res).toEqual({
      type: 'paragraph',
      children: [{ text: 'hello world' }],
    })
  })

  it('with children', () => {
    const $elem = $('<p></p>')
    const children = [{ text: 'hello ' }, { text: 'world', bold: true }]

    // parse
    const res = parseParagraphHtmlConf.parseElemHtml($elem[0], children, editor)
    expect(res).toEqual({
      type: 'paragraph',
      children: [{ text: 'hello ' }, { text: 'world', bold: true }],
    })
  })
})


================================================
FILE: packages/basic-modules/__tests__/paragraph/plugin.test.ts
================================================
/**
 * @description paragraph plugin test
 * @author wangfupeng
 */

import { Editor, Transforms, Point } from 'slate'
import { DomEditor, IDomEditor } from '@wangeditor/core'
import createEditor from '../../../../tests/utils/create-editor'
import withParagraph from '../../src/modules/paragraph/plugin'

let editor: IDomEditor
let startLocation: Point
describe('paragraph plugin', () => {
  beforeEach(() => {
    editor = withParagraph(createEditor())
    startLocation = Editor.start(editor, [])
  })

  it('delete to clear text', () => {
    editor.select(startLocation)
    Transforms.setNodes(editor, { type: 'header1' }) // 设置 header
    editor.deleteBackward('character') // 向后删除
    const selectedParagraph1 = DomEditor.getSelectedNodeByType(editor, 'paragraph')
    expect(selectedParagraph1).not.toBeNull() // 执行删除后,header 变为 paragraph

    Transforms.setNodes(editor, { type: 'blockquote' }) // 设置 blockquote
    editor.deleteForward('character') // 向前删除
    const selectedParagraph2 = DomEditor.getSelectedNodeByType(editor, 'paragraph')
    expect(selectedParagraph2).not.toBeNull() // 执行删除后,header 变为 paragraph
  })
})


================================================
FILE: packages/basic-modules/__tests__/paragraph/render-elem.test.ts
================================================
/**
 * @description paragraph render elem test
 * @author wangfupeng
 */

import createEditor from '../../../../tests/utils/create-editor'
import { renderParagraphConf } from '../../src/modules/paragraph/render-elem'

describe('paragraph - render elem', () => {
  const editor = createEditor()

  it('render paragraph', () => {
    expect(renderParagraphConf.type).toBe('paragraph')

    const elem = { type: 'paragraph', children: [] }
    const vnode = renderParagraphConf.renderElem(elem, null, editor)
    expect(vnode.sel).toBe('p')
  })
})


================================================
FILE: packages/basic-modules/__tests__/text-style/menu/clear-style-menu.test.ts
================================================
/**
 * @description clear style menu test
 * @author wangfupeng
 */

import { Editor } from 'slate'
import createEditor from '../../../../../tests/utils/create-editor'
import ClearStyleMenu from '../../../src/modules/text-style/menu/ClearStyleMenu'

describe('clear style menu', () => {
  let editor = createEditor()
  const startLocation = Editor.start(editor, [])
  const menu = new ClearStyleMenu()

  afterEach(() => {
    editor.select(startLocation)
    editor.clear()
  })

  it('exec', () => {
    editor.select(startLocation)
    editor.insertText('hello')

    editor.select([])
    editor.addMark('bold', true)
    editor.addMark('italic', true)

    menu.exec(editor, '') // 清空样式

    const marks = Editor.marks(editor) as any
    expect(marks.bold).toBeUndefined()
    expect(marks.italic).toBeUndefined()
  })
})


================================================
FILE: packages/basic-modules/__tests__/text-style/menu/menus.test.ts
================================================
/**
 * @description style menus test
 * @author wangfupeng
 */

import { Editor, Transforms, Element } from 'slate'
import createEditor from '../../../../../tests/utils/create-editor'
import BoldMenu from '../../../src/modules/text-style/menu/BoldMenu'
import CodeMenu from '../../../src/modules/text-style/menu/CodeMenu'
import ItalicMenu from '../../../src/modules/text-style/menu/ItalicMenu'
import SubMenu from '../../../src/modules/text-style/menu/SubMenu'
import SupMenu from '../../../src/modules/text-style/menu/SupMenu'
import ThroughMenu from '../../../src/modules/text-style/menu/ThroughMenu'
import UnderlineMenu from '../../../src/modules/text-style/menu/UnderlineMenu'

const MENU_INFO_LIST = [
  { mark: 'bold', menu: new BoldMenu() },
  { mark: 'code', menu: new CodeMenu() },
  { mark: 'italic', menu: new ItalicMenu() },
  { mark: 'sub', menu: new SubMenu() },
  { mark: 'sup', menu: new SupMenu() },
  { mark: 'through', menu: new ThroughMenu() },
  { mark: 'underline', menu: new UnderlineMenu() },
]

describe('text style menus', () => {
  let editor = createEditor()
  const startLocation = Editor.start(editor, [])

  afterEach(() => {
    editor.select(startLocation)
    editor.clear()
  })

  // getValue 已经被 isActive 覆盖

  it('is active', () => {
    MENU_INFO_LIST.forEach(info => {
      const { mark, menu } = info

      editor.select(startLocation)
      editor.clear()
      editor.insertText('hello')
      expect(menu.isActive(editor)).toBeFalsy()

      editor.select([])
      editor.addMark(mark, true)
      expect(menu.isActive(editor)).toBeTruthy()
    })
  })

  it('is disable', () => {
    MENU_INFO_LIST.forEach(info => {
      const { mark, menu } = info

      editor.select(startLocation)
      editor.clear()
      editor.insertText('hello')
      expect(menu.isDisabled(editor)).toBeFalsy() // 正常文字,不禁用

      editor.insertNode({
        type: 'pre',
        children: [
          {
            type: 'code',
            children: [{ text: 'var' }],
          } as Element,
        ],
      } as Element)
      expect(menu.isDisabled(editor)).toBeTruthy() // 选中代码块,禁用各个 menu
    })
  })

  it('exec', () => {
    MENU_INFO_LIST.forEach(info => {
      const { mark, menu } = info

      editor.select(startLocation)
      editor.clear()
      editor.insertText('hello')
      editor.select([])

      // 增加 mark
      menu.exec(editor, false)
      const marks1 = Editor.marks(editor) as any
      expect(marks1[mark]).toBeTruthy()

      // 取消 mark
      editor.select([])
      menu.exec(editor, true)
      const marks2 = Editor.marks(editor) as any
      expect(marks2[mark]).toBeUndefined()
    })
  })
})


================================================
FILE: packages/basic-modules/__tests__/text-style/parse-html.test.ts
================================================
/**
 * @description parse html test
 * @author wangfupeng
 */

// import { $ } from 'dom7'
// import { parseStyleHtml } from '../../../../packages/basic-modules/src/modules/text-style/parse-style-html'

describe('text style - parse style html', () => {
  it('占位', () => {
    expect(1 + 1).toBe(2)
  })
  // TODO 执行以下代码会有 Dom7 一个怪异的 bug ,先暂且注释,后面再解决 wangfupeng 2022.01.17

  // it('bold', () => {
  //   const $text = $('<b></b>')
  //   const textNode = { text: 'hello' }

  //   // parse style
  //   const res = parseStyleHtml($text[0], textNode)
  //   expect(res).toEqual({
  //     text: 'hello',
  //     bold: true,
  //   })
  // })

  // // italic underline... 等
})


================================================
FILE: packages/basic-modules/__tests__/text-style/parse-style-html.test.ts
================================================
import { parseStyleHtml } from '../../src/modules/text-style/parse-style-html'
import $ from '../../src/utils/dom'
import createEditor from '../../../../tests/utils/create-editor'

describe('parse style html', () => {
  const editor = createEditor()

  it('it should return directly if give node that type is not text', () => {
    const element = $('<p></p>')
    const node = { type: 'paragraph', children: [] }
    expect(parseStyleHtml(element[0], node, editor)).toEqual(node)
  })

  it('it should do nothing if give not exist element', () => {
    const element = $('#text')
    const node = { type: 'paragraph', children: [] }
    expect(parseStyleHtml(element[0], node, editor)).toEqual(node)
  })

  it('it should set bold property for node if give strong element', () => {
    const element = $('<strong></strong>')
    const node = { text: 'text' }
    expect(parseStyleHtml(element[0], node, editor)).toEqual({ ...node, bold: true })
  })

  it('it should set bold property for node if give b element', () => {
    const element = $('<b></b>')
    const node = { text: 'text' }
    expect(parseStyleHtml(element[0], node, editor)).toEqual({ ...node, bold: true })
  })

  it('it should set italic property for node if give i element', () => {
    const element = $('<i></i>')
    const node = { text: 'text' }
    expect(parseStyleHtml(element[0], node, editor)).toEqual({ ...node, italic: true })
  })

  it('it should set italic property for node if give em element', () => {
    const element = $('<em></em>')
    const node = { text: 'text' }
    expect(parseStyleHtml(element[0], node, editor)).toEqual({ ...node, italic: true })
  })

  it('it should set underline property for node if give u element', () => {
    const element = $('<u></u>')
    const node = { text: 'text' }
    expect(parseStyleHtml(element[0], node, editor)).toEqual({ ...node, underline: true })
  })

  it('it should set through property for node if give s element', () => {
    const element = $('<s></s>')
    const node = { text: 'text' }
    expect(parseStyleHtml(element[0], node, editor)).toEqual({ ...node, through: true })
  })

  it('it should set through property for node if give strike element', () => {
    const element = $('<strike></strike>')
    const node = { text: 'text' }
    expect(parseStyleHtml(element[0], node, editor)).toEqual({ ...node, through: true })
  })

  it('it should set sub property for node if give sub element', () => {
    const element = $('<sub></sub>')
    const node = { text: 'text' }
    expect(parseStyleHtml(element[0], node, editor)).toEqual({ ...node, sub: true })
  })

  it('it should set sup property for node if give sup element', () => {
    const element = $('<sup></sup>')
    const node = { text: 'text' }
    expect(parseStyleHtml(element[0], node, editor)).toEqual({ ...node, sup: true })
  })

  it('it should set code property for node if give code element', () => {
    const element = $('<code></code>')
    const node = { text: 'text' }
    expect(parseStyleHtml(element[0], node, editor)).toEqual({ ...node, code: true })
  })
})


================================================
FILE: packages/basic-modules/__tests__/text-style/text-style.test.tsx
================================================
/**
 * @description text style test
 * @author wangfupeng
 */

import { jsx } from 'snabbdom'
import { renderStyle } from '../../src/modules/text-style/render-style'
import { StyledText } from '../../src/modules/text-style/custom-types'

describe('text style - render text style', () => {
  it('render text style', () => {
    const vnode = <span>hello</span>
    let newVnode

    const textNode: StyledText = { text: '' }

    textNode.bold = true
    // @ts-ignore 忽略 vnode 格式
    newVnode = renderStyle(textNode, vnode)
    expect(newVnode.sel).toBe('strong')

    textNode.code = true
    // @ts-ignore 忽略 vnode 格式
    newVnode = renderStyle(textNode, vnode)
    expect(newVnode.sel).toBe('code')

    textNode.italic = true
    // @ts-ignore 忽略 vnode 格式
    newVnode = renderStyle(textNode, vnode)
    expect(newVnode.sel).toBe('em')

    textNode.underline = true
    // @ts-ignore 忽略 vnode 格式
    newVnode = renderStyle(textNode, vnode)
    expect(newVnode.sel).toBe('u')

    textNode.through = true
    // @ts-ignore 忽略 vnode 格式
    newVnode = renderStyle(textNode, vnode)
    expect(newVnode.sel).toBe('s')

    textNode.sub = true
    // @ts-ignore 忽略 vnode 格式
    newVnode = renderStyle(textNode, vnode)
    expect(newVnode.sel).toBe('sub')

    textNode.sup = true
    // @ts-ignore 忽略 vnode 格式
    newVnode = renderStyle(textNode, vnode)
    expect(newVnode.sel).toBe('sup')
  })
})


================================================
FILE: packages/basic-modules/__tests__/text-style/text-to-html.test.ts
================================================
/**
 * @description text to html test
 * @author wangfupeng
 */

import { styleToHtml } from '../../src/modules/text-style/style-to-html'

describe('text style - text to html', () => {
  it('text to html', () => {
    const textNode = {
      text: '',
      bold: true,
      italic: true,
      underline: true,
      code: true,
      through: true,
      sub: true,
      sup: true,
    }

    const html1 = styleToHtml(textNode, 'hello')
    expect(html1).toBe(
      '<sup><sub><s><u><em><code><strong>hello</strong></code></em></u></s></sub></sup>'
    )

    const html2 = styleToHtml(textNode, '<span>world</span>')
    expect(html2).toBe(
      '<span><sup><sub><s><u><em><code><strong>world</strong></code></em></u></s></sub></sup></span>'
    )
  })
})


================================================
FILE: packages/basic-modules/__tests__/todo/elem-to-html.test.ts
================================================
/**
 * @description todo elem to html test
 * @author wangfupeng
 */

import { todoToHtmlConf } from '../../src/modules/todo/elem-to-html'

describe('todo - elem to html', () => {
  it('todo elem to html', () => {
    expect(todoToHtmlConf.type).toBe('todo')

    const todoNode1 = {
      type: 'todo',
      checked: true,
      children: [{ text: '' }],
    }
    const html1 = todoToHtmlConf.elemToHtml(todoNode1, 'hello')
    expect(html1).toBe(
      `<div data-w-e-type="todo"><input type="checkbox" disabled checked>hello</div>`
    )

    const todoNode2 = {
      type: 'todo',
      checked: false,
      children: [{ text: '' }],
    }
    const html2 = todoToHtmlConf.elemToHtml(todoNode2, 'hello')
    expect(html2).toBe(`<div data-w-e-type="todo"><input type="checkbox" disabled >hello</div>`)
  })
})


================================================
FILE: packages/basic-modules/__tests__/todo/menu/todo-menu.test.ts
================================================
/**
 * @description todo-menu test
 * @author wangfupeng
 */

import { Editor, Transforms } from 'slate'
import createEditor from '../../../../../tests/utils/create-editor'
import TodoMenu from '../../../src/modules/todo/menu/Todo'

describe('todo-menu', () => {
  let editor: any
  let startLocation: any
  const menu = new TodoMenu()

  beforeEach(() => {
    editor = createEditor()
    startLocation = Editor.start(editor, [])
  })

  afterEach(() => {
    editor = null
    startLocation = null
  })

  it('get value', () => {
    expect(menu.getValue(editor)).toBe('')
  })

  it('is active', () => {
    editor.select(startLocation)
    expect(menu.isActive(editor)).toBeFalsy()

    // @ts-ignore
    Transforms.setNodes(editor, { type: 'todo' })
    expect(menu.isActive(editor)).toBeTruthy()
  })

  it('is disable - paragraph and todo', () => {
    editor.select(startLocation)
    expect(menu.isDisabled(editor)).toBeFalsy()

    // @ts-ignore
    Transforms.setNodes(editor, { type: 'todo' })
    expect(menu.isDisabled(editor)).toBeFalsy()
  })

  it('is disable - list', () => {
    editor.select(startLocation)
    editor.insertNode({
      type: 'bulleted-list',
      children: [
        {
          type: 'list-item',
          children: [{ text: 'hello' }],
        },
      ],
    })
    expect(menu.isDisabled(editor)).toBeTruthy()
  })

  it('is disable - table', () => {
    editor.select(startLocation)
    editor.insertNode({
      type: 'table',
      children: [
        {
          type: 'table-row',
          children: [
            {
              type: 'table-cell',
              children: [{ text: 'hello' }],
            },
          ],
        },
      ],
    })
    expect(menu.isDisabled(editor)).toBeTruthy()
  })

  it('is disable - pre/code', () => {
    editor.select(startLocation)
    editor.insertNode({
      type: 'pre',
      children: [
        {
          type: 'code',
          children: [{ text: 'hello' }],
        },
      ],
    })
    expect(menu.isDisabled(editor)).toBeTruthy()
  })

  it('exec - paragraph to todo', () => {
    editor.select(startLocation)
    menu.exec(editor, '')

    const todoElems = editor.getElemsByType('todo')
    expect(todoElems.length).toBe(1)
  })

  it('exec - todo to paragraph', () => {
    editor.select(startLocation)
    // @ts-ignore
    Transforms.setNodes(editor, { type: 'todo' })
    menu.exec(editor, '')

    const todoElems = editor.getElemsByType('todo')
    expect(todoElems.length).toBe(0)
  })
})


================================================
FILE: packages/basic-modules/__tests__/todo/parse-html.test.ts
================================================
/**
 * @description todo parse html test
 * @author wangfupeng
 */

import { $ } from 'dom7'
import createEditor from '../../../../tests/utils/create-editor'
import { parseHtmlConf } from '../../src/modules/todo/parse-elem-html'

describe('todo - parse html', () => {
  const editor = createEditor()

  it('with children, checked', () => {
    const $todo = $('<div data-w-e-type="todo"><input type="checkbox" disabled checked>hello</div>')

    // match selector
    expect($todo[0].matches(parseHtmlConf.selector)).toBeTruthy()

    // parse
    const res = parseHtmlConf.parseElemHtml($todo[0], [], editor)
    expect(res).toEqual({
      type: 'todo',
      checked: true,
      children: [{ text: 'hello' }],
    })
  })

  it('without children, unchecked', () => {
    const $todo = $('<div data-w-e-type="todo"><input type="checkbox" disabled></div>')
    const children = [{ text: 'hello ' }, { text: 'world', bold: true }]

    // match selector
    expect($todo[0].matches(parseHtmlConf.selector)).toBeTruthy()

    // parse
    const res = parseHtmlConf.parseElemHtml($todo[0], children, editor)
    expect(res).toEqual({
      type: 'todo',
      checked: false,
      children: [{ text: 'hello ' }, { text: 'world', bold: true }],
    })
  })
})


================================================
FILE: packages/basic-modules/__tests__/todo/plugin.test.ts
================================================
/**
 * @description todo plugin test
 * @author wangfupeng
 */

import withTodo from '../../src/modules/todo/plugin'
import createEditor from '../../../../tests/utils/create-editor'

describe('todo - plugin', () => {
  it('delete backward', () => {
    const editor = withTodo(
      createEditor({
        content: [{ type: 'todo', children: [{ text: '' }] }],
      })
    )
    editor.select({
      path: [0, 0],
      offset: 0,
    })

    const todoElems1 = editor.getElemsByType('todo')
    expect(todoElems1.length).toBe(1)

    editor.deleteBackward('character')

    const todoElems2 = editor.getElemsByType('todo')
    expect(todoElems2.length).toBe(0)
  })
})


================================================
FILE: packages/basic-modules/__tests__/todo/pre-parse-html.test.ts
================================================
/**
 * @description todo pre-parse html
 * @author wangfupeng
 */

import { $ } from 'dom7'
import { preParseHtmlConf } from '../../src/modules/todo/pre-parse-html'

describe('todo - pre-parse html', () => {
  it('pre-parse html', () => {
    // v4 todo html 格式
    const $ul = $(
      '<ul class="w-e-todo"><li><span contenteditable="false"><input type="checkbox"/></span>hello <b>world</b></li></ul>'
    )

    // match selector
    expect($ul[0].matches(preParseHtmlConf.selector)).toBeTruthy()

    // parse
    const res = preParseHtmlConf.preParseHtml($ul[0])
    expect(res.outerHTML).toBe(
      '<div data-w-e-type="todo"><input type="checkbox">hello <b>world</b></div>'
    )
  })
})


================================================
FILE: packages/basic-modules/__tests__/todo/render-elem.test.ts
================================================
/**
 * @description todo render elem
 * @author wangfupeng
 */

import createEditor from '../../../../tests/utils/create-editor'
import { renderTodoConf } from '../../src/modules/todo/render-elem'

describe('todo - render elem', () => {
  const editor = createEditor()

  it('render elem', () => {
    expect(renderTodoConf.type).toBe('todo')

    const todo = { type: 'todo', checked: true, children: [{ text: '' }] }
    const vnode = renderTodoConf.renderElem(todo, null, editor) as any
    expect(vnode.sel).toBe('div')
    expect(vnode.children.length).toBe(2)

    const spanForInput = vnode.children[0]
    expect(spanForInput.sel).toBe('span')
    expect(spanForInput.data.contentEditable).toBe(false)

    const input = spanForInput.children[0]
    expect(input.sel).toBe('input')
    expect(input.data.type).toBe('checkbox')
    expect(input.data.checked).toBe(true)
    expect(typeof input.data.on.change).toBe('function')
  })
})


================================================
FILE: packages/basic-modules/__tests__/undo-redo/redo-menu.test.ts
================================================
/**
 * @description redo menu test
 * @author wangfupeng
 */

import { Editor } from 'slate'
import createEditor from '../../../../tests/utils/create-editor'
import RedoMenu from '../../src/modules/undo-redo/menu/RedoMenu'

describe('redo menu', () => {
  const editor = createEditor()
  const menu = new RedoMenu()
  const location = Editor.start(editor, []) // 选区位置

  it('tag', () => {
    expect(menu.tag).toBe('button')
  })

  it('get value', () => {
    expect(menu.getValue(editor)).toBe('')
  })

  it('is active', () => {
    expect(menu.isActive(editor)).toBeFalsy()
  })

  it('is disable', () => {
    // 有选区
    editor.select(location)
    expect(menu.isDisabled(editor)).toBeFalsy()

    // 无选区
    editor.deselect()
    expect(menu.isDisabled(editor)).toBeTruthy()
  })

  it('exec', () => {
    const text = editor.getText()

    editor.select(location)
    editor.insertText('xxx')
    if (typeof editor.undo === 'function') {
      editor.undo()
    }
    menu.exec(editor, '')

    const newText = editor.getText()
    expect(newText).toBe(text + 'xxx')
  })
})


================================================
FILE: packages/basic-modules/__tests__/undo-redo/undo-menu.test.ts
================================================
/**
 * @description undo menu test
 * @author wangfupeng
 */

import { Editor } from 'slate'
import createEditor from '../../../../tests/utils/create-editor'
import UndoMenu from '../../src/modules/undo-redo/menu/UndoMenu'

describe('undo menu', () => {
  const editor = createEditor()
  const menu = new UndoMenu()
  const location = Editor.start(editor, []) // 选区位置

  it('tag', () => {
    expect(menu.tag).toBe('button')
  })

  it('get value', () => {
    expect(menu.getValue(editor)).toBe('')
  })

  it('is active', () => {
    expect(menu.isActive(editor)).toBeFalsy()
  })

  it('is disable', () => {
    // 有选区
    editor.select(location)
    expect(menu.isDisabled(editor)).toBeFalsy()

    // 无选区
    editor.deselect()
    expect(menu.isDisabled(editor)).toBeTruthy()
  })

  it('exec', () => {
    const text = editor.getText()

    editor.select(location)
    editor.insertText('xxx')
    menu.exec(editor, '')

    const newText = editor.getText()
    expect(newText).toBe(text)
  })
})


================================================
FILE: packages/basic-modules/package.json
================================================
{
  "name": "@wangeditor/basic-modules",
  "version": "1.1.7",
  "description": "wangEditor basic modules",
  "author": "wangfupeng1988 <wangfupeng1988@163.com>",
  "contributors": [],
  "homepage": "https://github.com/wangeditor-team/wangEditor#readme",
  "license": "MIT",
  "types": "dist/basic-modules/src/index.d.ts",
  "main": "dist/index.js",
  "module": "dist/index.esm.js",
  "browser": {
    "./dist/index.js": "./dist/index.js",
    "./dist/index.esm.js": "./dist/index.esm.js"
  },
  "directories": {
    "lib": "dist",
    "test": "__tests__"
  },
  "files": [
    "dist"
  ],
  "publishConfig": {
    "access": "public",
    "registry": "https://registry.npmjs.com/"
  },
  "repository": {
    "type": "git",
    "url": "git+https://github.com/wangeditor-team/wangEditor.git"
  },
  "scripts": {
    "test": "jest",
    "test-c": "jest --coverage",
    "dev": "cross-env NODE_ENV=development rollup -c rollup.config.js",
    "dev-watch": "cross-env NODE_ENV=development rollup -c rollup.config.js -w",
    "build": "cross-env NODE_ENV=production rollup -c rollup.config.js",
    "dev-size-stats": "cross-env NODE_ENV=development:size_stats rollup -c rollup.config.js",
    "size-stats": "cross-env NODE_ENV=production:size_stats rollup -c rollup.config.js"
  },
  "bugs": {
    "url": "https://github.com/wangeditor-team/wangEditor/issues"
  },
  "peerDependencies": {
    "@wangeditor/core": "1.x",
    "dom7": "^3.0.0",
    "lodash.throttle": "^4.1.1",
    "nanoid": "^3.2.0",
    "slate": "^0.72.0",
    "snabbdom": "^3.1.0"
  },
  "dependencies": {
    "is-url": "^1.2.4"
  },
  "devDependencies": {
    "@types/is-url": "^1.2.29"
  }
}


================================================
FILE: packages/basic-modules/rollup.config.js
================================================
import { createRollupConfig, IS_PRD } from '../../build/create-rollup-config'
import pkg from './package.json'

const name = 'WangEditorBasicModules'

const configList = []

// esm
const esmConf = createRollupConfig({
  output: {
    file: pkg.module,
    format: 'esm',
    name,
  },
})
configList.push(esmConf)

// umd
const umdConf = createRollupConfig({
  output: {
    file: pkg.main,
    format: 'umd',
    name,
  },
})
configList.push(umdConf)

export default configList


================================================
FILE: packages/basic-modules/src/assets/blockquote.less
================================================
@import "../../../vars.less";

.w-e-text-container [data-slate-editor] blockquote {
  display: block;
  border-left: 8px solid @textarea-selected-border-color;
  padding: 10px 10px;
  margin: 10px 0;
  line-height: 1.5;
  font-size: 100%;
  background-color: @textarea-slight-bg-color;
}


================================================
FILE: packages/basic-modules/src/assets/code-block.less
================================================
@import "../../../vars.less";

.w-e-text-container [data-slate-editor] pre>code {
  display: block;
  border: 1px solid @textarea-slight-border-color;
  border-radius: 4px 4px;
  text-indent: 0;
  background-color: @textarea-slight-bg-color;
  padding: 10px;
  font-size: @size;
}


================================================
FILE: packages/basic-modules/src/assets/color.less
================================================
@import "../../../vars.less";

.w-e-panel-content-color {
  list-style: none;
  text-align: left;
  width: 230px;

  li {
    display: inline-block;
    padding: 2px;
    cursor: pointer;
    border-radius: 3px 3px;
    border: 1px solid @toolbar-bg-color;

    &:hover {
      border-color: @toolbar-color;
    }

    .color-block {
      width: 17px;
      height: 17px;
      border: 1px solid @toolbar-border-color;
      border-radius: 3px 3px;
    }
  }

  .active {
    border-color: @toolbar-color;
  }

  .clear {
    width: 100%;
    line-height: 1.5;
    margin-bottom: 5px;

    svg {
      width: 16px;
      height: 16px;
      margin-bottom: -4px;
    }
  }
}

================================================
FILE: packages/basic-modules/src/assets/divider.less
================================================
@import "../../../vars.less";

.w-e-textarea-divider {
  padding: 20px 20px;
  margin: 20px auto;
  border-radius: 3px;

  // &:hover {
  //   background-color: @textarea-slight-bg-color;
  // }

  hr {
    display: block;
    border: 0;
    height: 1px;
    background-color: @textarea-border-color;
  }
}


================================================
FILE: packages/basic-modules/src/assets/emotion.less
================================================
@import "../../../vars.less";

.w-e-panel-content-emotion {
  list-style: none;
  text-align: left;
  width: 300px;
  font-size: 20px;

  li {
    display: inline-block;
    padding: 0 5px;
    cursor: pointer;
    border-radius: 3px 3px;

    &:hover {
      background-color: @textarea-slight-bg-color;
    }
  }
}

================================================
FILE: packages/basic-modules/src/assets/image.less
================================================
@import "../../../vars.less";

// 拖拽,修改图片尺寸
.w-e-text-container [data-slate-editor] {
  .w-e-image-container {
    display: inline-block;
    margin: 0 3px; // 从 10px 改为 3px ,可规避 issue 4523

    &:hover {
      box-shadow: 0 0 0 2px @textarea-selected-border-color;
    }
  }
  .w-e-selected-image-container {
    position: relative;
    overflow: hidden;

    .w-e-image-dragger {
      width: 7px;
      height: 7px;
      background-color: @textarea-handler-bg-color;
      position: absolute;
    }
    .left-top {
      top: 0;
      left: 0;
      cursor: nwse-resize;
    }
    .right-top {
      top: 0;
      right: 0;
      cursor: nesw-resize;
    }
    .left-bottom {
      left: 0;
      bottom: 0;
      cursor: nesw-resize;
    }
    .right-bottom {
      right: 0;
      bottom: 0;
      cursor: nwse-resize;
    }

    // 选中之后,不需要 hover 效果
    &:hover {
      box-shadow: none;
    }
  }
}

// 禁用编辑器时,img hover 不要有样式
.w-e-text-container [contenteditable="false"] {
  .w-e-image-container {
    &:hover {
      box-shadow: none;
    }
  }
}

================================================
FILE: packages/basic-modules/src/assets/index.less
================================================
@import "simple-style.less";
@import "color.less";
@import "blockquote.less";
@import "emotion.less";
@import "divider.less";
@import "blockquote.less";
@import "code-block.less";
@import "image.less";


================================================
FILE: packages/basic-modules/src/assets/simple-style.less
================================================
@import "../../../vars.less";

.w-e-text-container [data-slate-editor] code {
  font-family: monospace;
  background-color: @textarea-slight-bg-color;
  padding: 3px;
  border-radius: 3px;
}


================================================
FILE: packages/basic-modules/src/constants/icon-svg.ts
================================================
/**
 * @description icon svg
 * @author wangfupeng
 */

/**
 * 【注意】svg 字符串的长度 ,否则会导致代码体积过大
 * 尽量选择 https://www.iconfont.cn/collections/detail?spm=a313x.7781069.0.da5a778a4&cid=20293
 * 找不到再从 iconfont.com 搜索
 */

// 加粗
export const BOLD_SVG =
  '<svg viewBox="0 0 1024 1024"><path d="M707.872 484.64A254.88 254.88 0 0 0 768 320c0-141.152-114.848-256-256-256H192v896h384c141.152 0 256-114.848 256-256a256.096 256.096 0 0 0-124.128-219.36zM384 192h101.504c55.968 0 101.504 57.408 101.504 128s-45.536 128-101.504 128H384V192z m159.008 640H384v-256h159.008c58.464 0 106.016 57.408 106.016 128s-47.552 128-106.016 128z"></path></svg>'

// 下划线
export const UNDER_LINE_SVG =
  '<svg viewBox="0 0 1024 1024"><path d="M704 64l128 0 0 416c0 159.072-143.264 288-320 288s-320-128.928-320-288l0-416 128 0 0 416c0 40.16 18.24 78.688 51.36 108.512 36.896 33.216 86.848 51.488 140.64 51.488s103.744-18.304 140.64-51.488c33.12-29.792 51.36-68.352 51.36-108.512l0-416zM192 832l640 0 0 128-640 0z"></path></svg>'

// 斜体
export const ITALIC_SVG =
  '<svg viewBox="0 0 1024 1024"><path d="M896 64v64h-128L448 896h128v64H128v-64h128L576 128h-128V64z"></path></svg>'

// 删除线
export const THROUGH_SVG =
  '<svg viewBox="0 0 1024 1024"><path d="M1024 512v64h-234.496c27.52 38.496 42.496 82.688 42.496 128 0 70.88-36.672 139.04-100.576 186.976C672.064 935.488 594.144 960 512 960s-160.064-24.512-219.424-69.024C228.64 843.04 192 774.88 192 704h128c0 69.376 87.936 128 192 128s192-58.624 192-128-87.936-128-192-128H0v-64h299.52a385.984 385.984 0 0 1-6.944-5.024C228.64 459.04 192 390.88 192 320s36.672-139.04 100.576-186.976C351.936 88.512 429.856 64 512 64s160.064 24.512 219.424 69.024C795.328 180.96 832 249.12 832 320h-128c0-69.376-87.936-128-192-128s-192 58.624-192 128 87.936 128 192 128c78.976 0 154.048 22.688 212.48 64H1024z"></path></svg>'

// 代码
export const CODE_SVG =
  '<svg viewBox="0 0 1024 1024"><path d="M576 736l96 96 320-320L672 192l-96 96 224 224zM448 288l-96-96L32 512l320 320 96-96-224-224z"></path></svg>'

// 清除格式
export const ERASER_SVG =
  '<svg viewBox="0 0 1024 1024"><path d="M969.382408 288.738615l-319.401123-270.852152a67.074236 67.074236 0 0 0-96.459139 5.74922l-505.931379 574.922021a68.35184 68.35184 0 0 0-17.886463 47.910169 74.101061 74.101061 0 0 0 24.274486 47.910168l156.50655 132.232065h373.060512L975.131628 383.281347a67.074236 67.074236 0 0 0-5.74922-96.459139z m-440.134747 433.746725H264.144729l-90.071117-78.572676c-5.74922-5.74922-12.137243-12.137243-12.137243-17.886463a36.411728 36.411728 0 0 1 5.749221-24.274485l210.804741-240.828447 265.102932 228.691204z m-439.495945 180.781036h843.218964a60.047411 60.047411 0 1 1 0 120.733624H89.751716a60.047411 60.047411 0 1 1 0-120.733624z m0 0"></path></svg>'

// 链接
export const LINK_SVG =
  '<svg viewBox="0 0 1024 1024"><path d="M440.224 635.776a51.84 51.84 0 0 1-36.768-15.232c-95.136-95.136-95.136-249.92 0-345.056l192-192C641.536 37.408 702.816 12.032 768 12.032s126.432 25.376 172.544 71.456c95.136 95.136 95.136 249.92 0 345.056l-87.776 87.776a51.968 51.968 0 1 1-73.536-73.536l87.776-87.776a140.16 140.16 0 0 0 0-197.984c-26.432-26.432-61.6-40.992-99.008-40.992s-72.544 14.56-99.008 40.992l-192 192a140.16 140.16 0 0 0 0 197.984 51.968 51.968 0 0 1-36.768 88.768z"></path><path d="M256 1012a242.4 242.4 0 0 1-172.544-71.456c-95.136-95.136-95.136-249.92 0-345.056l87.776-87.776a51.968 51.968 0 1 1 73.536 73.536l-87.776 87.776a140.16 140.16 0 0 0 0 197.984c26.432 26.432 61.6 40.992 99.008 40.992s72.544-14.56 99.008-40.992l192-192a140.16 140.16 0 0 0 0-197.984 51.968 51.968 0 1 1 73.536-73.536c95.136 95.136 95.136 249.92 0 345.056l-192 192A242.4 242.4 0 0 1 256 1012z"></path></svg>'

// 取消链接
export const UN_LINK_SVG =
  '<svg viewBox="0 0 1024 1024"><path d="M608.16328 811.815036c9.371954 9.371954 9.371954 24.56788 0 33.941834l-89.347563 89.347564c-118.525421 118.523421-311.38448 118.531421-429.919901 0-118.527421-118.529421-118.527421-311.39048 0-429.917901l89.349564-89.349563c9.371954-9.371954 24.56788-9.371954 33.941834 0l79.195613 79.195613c9.371954 9.371954 9.371954 24.56788 0 33.941834l-89.349563 89.347564c-56.143726 56.145726-56.143726 147.49928 0 203.645005 56.143726 56.143726 147.49928 56.145726 203.647005 0l89.347564-89.347563c9.371954-9.371954 24.56788-9.371954 33.941834 0l79.193613 79.195613z m-113.135447-520.429459c9.371954 9.371954 24.56788 9.371954 33.941834 0l89.347564-89.347564c56.143726-56.149726 147.49928-56.145726 203.647006 0 56.143726 56.145726 56.143726 147.49928 0 203.645006l-89.349564 89.347564c-9.371954 9.371954-9.371954 24.56788 0 33.941834l79.195613 79.195613c9.371954 9.371954 24.56788 9.371954 33.941834 0l89.349564-89.349563c118.529421-118.529421 118.529421-311.38848 0-429.917901-118.531421-118.527421-311.38848-118.527421-429.919901 0l-89.347563 89.347564c-9.371954 9.371954-9.371954 24.56788 0 33.941834l79.193613 79.195613z m469.653707 718.556492l45.253779-45.253779c18.745908-18.745908 18.745908-49.13776 0-67.881669L127.195629 14.062931c-18.745908-18.745908-49.13776-18.745908-67.881669 0L14.058181 59.31871c-18.745908 18.745908-18.745908 49.13776 0 67.881669l882.74169 882.74169c18.745908 18.743908 49.13776 18.743908 67.881669 0z"></path></svg>'

// 编辑
export const PENCIL_SVG =
  '<svg viewBox="0 0 1024 1024"><path d="M864 0a160 160 0 0 1 128 256l-64 64-224-224 64-64c26.752-20.096 59.968-32 96-32zM64 736l-64 288 288-64 592-592-224-224L64 736z m651.584-372.416l-448 448-55.168-55.168 448-448 55.168 55.168z"></path></svg>'

// 外部(链接)
export const EXTERNAL_SVG =
  '<svg viewBox="0 0 1024 1024"><path d="M924.402464 1023.068211H0.679665V99.345412h461.861399v98.909208H99.596867v725.896389h725.896389V561.206811h98.909208z" p-id="10909"></path><path d="M930.805104 22.977336l69.965436 69.965436-453.492405 453.492404-69.965435-69.901489z" p-id="10910"></path><path d="M1022.464381 304.030081h-98.917201V99.345412H709.230573V0.428211h313.233808z"></path></svg>'

// 标题
export const HEADER_SVG =
  '<svg viewBox="0 0 1024 1024"><path d="M960 960c-51.2 0-102.4-3.2-153.6-3.2-51.2 0-99.2 3.2-150.4 3.2-19.2 0-28.8-22.4-28.8-38.4 0-51.2 57.6-28.8 86.4-48 19.2-12.8 19.2-60.8 19.2-80v-224-19.2c-9.6-3.2-19.2-3.2-28.8-3.2H320c-9.6 0-19.2 0-28.8 3.2V780.8c0 22.4 0 80 22.4 92.8 28.8 19.2 96-6.4 96 44.8 0 16-9.6 41.6-28.8 41.6-54.4 0-105.6-3.2-160-3.2-48 0-96 3.2-147.2 3.2-19.2 0-28.8-22.4-28.8-38.4 0-51.2 51.2-28.8 80-48 19.2-12.8 19.2-60.8 19.2-83.2V294.4c0-28.8 3.2-115.2-22.4-131.2-25.6-16-86.4 9.6-86.4-41.6 0-16 6.4-41.6 28.8-41.6 51.2 0 105.6 3.2 156.8 3.2 48 0 96-3.2 144-3.2 19.2 0 28.8 22.4 28.8 41.6 0 48-57.6 25.6-83.2 41.6-19.2 12.8-19.2 73.6-19.2 92.8v201.6c6.4 3.2 16 3.2 22.4 3.2h400c6.4 0 12.8 0 22.4-3.2V256c0-22.4 0-80-19.2-92.8-28.8-16-86.4 6.4-86.4-41.6 0-16 9.6-41.6 28.8-41.6 51.2 0 99.2 3.2 150.4 3.2 48 0 99.2-3.2 147.2-3.2 19.2 0 28.8 22.4 28.8 41.6 0 51.2-57.6 25.6-86.4 41.6-19.2 12.8-19.2 70.4-19.2 92.8v537.6c0 19.2 0 67.2 19.2 80 28.8 19.2 89.6-6.4 89.6 44.8 0 19.2-6.4 41.6-28.8 41.6z"></path></svg>'

// 字体颜色
export const FONT_COLOR_SVG =
  '<svg viewBox="0 0 1024 1024"><path d="M64 864h896v96H64zM360.58 576h302.85l81.53 224h102.16L579.24 64H444.77L176.89 800h102.16l81.53-224zM512 159.96L628.49 480H395.52L512 159.96z"></path></svg>'

// 背景颜色
export const BG_COLOR_SVG =
  '<svg viewBox="0 0 1024 1024"><path d="M510.030769 315.076923l84.676923 196.923077h-177.230769l76.8-196.923077h15.753846zM945.230769 157.538462v708.923076c0 43.323077-35.446154 78.769231-78.769231 78.769231H157.538462c-43.323077 0-78.769231-35.446154-78.769231-78.769231V157.538462c0-43.323077 35.446154-78.769231 78.769231-78.769231h708.923076c43.323077 0 78.769231 35.446154 78.769231 78.769231z m-108.307692 643.938461L600.615385 216.615385c-5.907692-11.815385-15.753846-19.692308-29.538462-19.692308h-139.815385c-11.815385 0-23.630769 7.876923-27.56923 19.692308l-216.615385 584.861538c-3.938462 11.815385 3.938462 25.6 17.723077 25.6h80.738462c11.815385 0 23.630769-9.846154 27.56923-21.661538l63.015385-175.261539h263.876923l68.923077 175.261539c3.938462 11.815385 15.753846 21.661538 27.569231 21.661538h80.738461c13.784615 0 23.630769-13.784615 19.692308-25.6z"></path></svg>'

// 清空(颜色)
export const CLEAN_SVG =
  '<svg viewBox="0 0 1024 1024"><path d="M236.8 128L896 787.2V128H236.8z m614.4 704L192 172.8V832h659.2zM192 64h704c38.4 0 64 25.6 64 64v704c0 38.4-25.6 64-64 64H192c-38.4 0-64-25.6-64-64V128c0-38.4 25.6-64 64-64z"></path></svg>'

// 图片
export const IMAGE_SVG =
  '<svg viewBox="0 0 1024 1024"><path d="M959.877 128l0.123 0.123v767.775l-0.123 0.122H64.102l-0.122-0.122V128.123l0.122-0.123h895.775zM960 64H64C28.795 64 0 92.795 0 128v768c0 35.205 28.795 64 64 64h896c35.205 0 64-28.795 64-64V128c0-35.205-28.795-64-64-64zM832 288.01c0 53.023-42.988 96.01-96.01 96.01s-96.01-42.987-96.01-96.01S682.967 192 735.99 192 832 234.988 832 288.01zM896 832H128V704l224.01-384 256 320h64l224.01-192z"></path></svg>'

// 垃圾桶(删除)
export const TRASH_SVG =
  '<svg viewBox="0 0 1024 1024"><path d="M826.8032 356.5312c-19.328 0-36.3776 15.6928-36.3776 35.0464v524.2624c0 19.328-16 34.56-35.328 34.56H264.9344c-19.328 0-35.5072-15.3088-35.5072-34.56V390.0416c0-19.328-14.1568-35.0464-33.5104-35.0464s-33.5104 15.6928-33.5104 35.0464V915.712c0 57.9328 44.6208 108.288 102.528 108.288H755.2c57.9328 0 108.0832-50.4576 108.0832-108.288V391.4752c-0.1024-19.2512-17.1264-34.944-36.48-34.944z" p-id="9577"></path><path d="M437.1712 775.7568V390.6048c0-19.328-14.1568-35.0464-33.5104-35.0464s-33.5104 15.616-33.5104 35.0464v385.152c0 19.328 14.1568 35.0464 33.5104 35.0464s33.5104-15.7184 33.5104-35.0464zM649.7024 775.7568V390.6048c0-19.328-17.0496-35.0464-36.3776-35.0464s-36.3776 15.616-36.3776 35.0464v385.152c0 19.328 17.0496 35.0464 36.3776 35.0464s36.3776-15.7184 36.3776-35.0464zM965.0432 217.0368h-174.6176V145.5104c0-57.9328-47.2064-101.76-104.6528-101.76h-350.976c-57.8304 0-105.3952 43.8528-105.3952 101.76v71.5264H54.784c-19.4304 0-35.0464 14.1568-35.0464 33.5104 0 19.328 15.616 33.5104 35.0464 33.5104h910.3616c19.328 0 35.0464-14.1568 35.0464-33.5104 0-19.3536-15.6928-33.5104-35.1488-33.5104z m-247.3728 0H297.3952V145.5104c0-19.328 18.2016-34.7648 37.4272-34.7648h350.976c19.1488 0 31.872 15.1296 31.872 34.7648v71.5264z"></path></svg>'

// 引用
export const QUOTE_SVG =
  '<svg viewBox="0 0 1024 1024"><path d="M894.6 907.1H605.4c-32.6 0-59-26.4-59-59V608.2l-4-14.9c0-315.9 125.5-485.1 376.5-507.5v59.8C752.7 180.4 711.3 315.8 711.3 442.4v41.2l31.5 12.3h151.8c32.6 0 59 26.4 59 59v293.2c0 32.5-26.4 59-59 59z m-472 0H133.4c-32.6 0-59-26.4-59-59V608.2l-4-14.9c0-315.9 125.5-485.1 376.5-507.5v59.8C280.7 180.4 239.3 315.8 239.3 442.4v41.2l31.5 12.3h151.8c32.6 0 59 26.4 59 59v293.2c0 32.5-26.4 59-59 59z"></path></svg>'

// 表情
export const EMOTION_SVG =
  '<svg viewBox="0 0 1024 1024"><path d="M512 1024C230.4 1024 0 793.6 0 512S230.4 0 512 0s512 230.4 512 512-230.4 512-512 512z m0-102.4c226.742857 0 409.6-182.857143 409.6-409.6S738.742857 102.4 512 102.4 102.4 285.257143 102.4 512s182.857143 409.6 409.6 409.6z m-204.8-358.4h409.6c0 113.371429-91.428571 204.8-204.8 204.8s-204.8-91.428571-204.8-204.8z m0-102.4c-43.885714 0-76.8-32.914286-76.8-76.8s32.914286-76.8 76.8-76.8 76.8 32.914286 76.8 76.8-32.914286 76.8-76.8 76.8z m409.6 0c-43.885714 0-76.8-32.914286-76.8-76.8s32.914286-76.8 76.8-76.8c43.885714 0 76.8 32.914286 76.8 76.8s-32.914286 76.8-76.8 76.8z"></path></svg>'

// fontSize
export const FONT_SIZE_SVG =
  '<svg viewBox="0 0 1024 1024"><path d="M64 512h384v128h-128V1024h-128V640h-128z m896-256H708.2496v768h-136.4992V256H320V128h640z"></path></svg>'

// 字体
export const FONT_FAMILY_SVG =
  '<svg viewBox="0 0 1024 1024"><path d="M956.788364 152.110545h-24.110546l23.924364 9.029819 0.186182 121.018181h-65.070546l-86.574545-130.048H566.551273v650.14691l130.048 64.977454v65.163636h-390.050909v-65.163636l129.954909-64.977454V152.110545H198.283636L111.429818 282.065455H46.545455V69.259636C46.545455 33.792 82.664727 22.062545 98.955636 22.062545h812.683637c23.738182 0 45.056 15.173818 45.056 41.053091V169.425455v-17.221819z"></path></svg>'

// 缩进 left
export const INDENT_LEFT_SVG =
  '<svg viewBox="0 0 1024 1024"><path d="M0 64h1024v128H0z m384 192h640v128H384z m0 192h640v128H384z m0 192h640v128H384zM0 832h1024v128H0z m256-512v384l-256-192z"></path></svg>'

// 缩进 right
export const INDENT_RIGHT_SVG =
  '<svg viewBox="0 0 1024 1024"><path d="M0 64h1024v128H0z m384 192h640v128H384z m0 192h640v128H384z m0 192h640v128H384zM0 832h1024v128H0z m0-128V320l256 192z"></path></svg>'

// 左对齐
export const JUSTIFY_LEFT_SVG =
  '<svg viewBox="0 0 1024 1024"><path d="M768 793.6v102.4H51.2v-102.4h716.8z m204.8-230.4v102.4H51.2v-102.4h921.6z m-204.8-230.4v102.4H51.2v-102.4h716.8zM972.8 102.4v102.4H51.2V102.4h921.6z"></path></svg>'

// 右对齐
export const JUSTIFY_RIGHT_SVG =
  '<svg viewBox="0 0 1024 1024"><path d="M972.8 793.6v102.4H256v-102.4h716.8z m0-230.4v102.4H51.2v-102.4h921.6z m0-230.4v102.4H256v-102.4h716.8zM972.8 102.4v102.4H51.2V102.4h921.6z"></path></svg>'

// 居中对齐
export const JUSTIFY_CENTER_SVG =
  '<svg viewBox="0 0 1024 1024"><path d="M870.4 793.6v102.4H153.6v-102.4h716.8z m102.4-230.4v102.4H51.2v-102.4h921.6z m-102.4-230.4v102.4H153.6v-102.4h716.8zM972.8 102.4v102.4H51.2V102.4h921.6z"></path></svg>'

// 两端对齐
export const JUSTIFY_JUSTIFY_SVG =
  '<svg viewBox="0 0 1024 1024"><path d="M0 64h1024v128H0z m0 192h1024v128H0z m0 192h1024v128H0z m0 192h1024v128H0z m0 192h1024v128H0z"></path></svg>'

// 行高
export const LINE_HEIGHT_SVG =
  '<svg viewBox="0 0 1024 1024"><path d="M964 788a8 8 0 0 1 8 8v98a8 8 0 0 1-8 8H438a8 8 0 0 1-8-8v-98a8 8 0 0 1 8-8h526zM198.93 144.306c6.668-5.798 16.774-5.094 22.573 1.574l122.26 140.582a16 16 0 0 1 3.927 10.5c0 8.836-7.164 16-16 16h-61.8a8 8 0 0 0-8 8v390.077h69.819a16 16 0 0 1 10.502 3.928c6.666 5.8 7.37 15.906 1.57 22.573L221.476 878.123a16 16 0 0 1-1.57 1.57c-6.668 5.8-16.774 5.097-22.574-1.57L75.051 737.538a16 16 0 0 1-3.928-10.5c0-8.837 7.163-16 16-16h69.822V312.96H87.127a16 16 0 0 1-10.502-3.928c-6.666-5.8-7.37-15.906-1.57-22.573l122.303-140.582a16 16 0 0 1 1.572-1.572zM964 465a8 8 0 0 1 8 8v98a8 8 0 0 1-8 8H438a8 8 0 0 1-8-8v-98a8 8 0 0 1 8-8h526z m0-323a8 8 0 0 1 8 8v98a8 8 0 0 1-8 8H438a8 8 0 0 1-8-8v-98a8 8 0 0 1 8-8h526z"></path></svg>'

// 撤销
export const UNDO_SVG =
  '<svg viewBox="0 0 1024 1024"><path d="M512 64A510.272 510.272 0 0 0 149.984 213.984L0.032 64v384h384L240.512 304.48A382.784 382.784 0 0 1 512.032 192c212.064 0 384 171.936 384 384 0 114.688-50.304 217.632-130.016 288l84.672 96a510.72 510.72 0 0 0 173.344-384c0-282.784-229.216-512-512-512z"></path></svg>'

// 重做
export const REDO_SVG =
  '<svg viewBox="0 0 1024 1024"><path d="M0.00032 576a510.72 510.72 0 0 0 173.344 384l84.672-96A383.136 383.136 0 0 1 128.00032 576C128.00032 363.936 299.93632 192 512.00032 192c106.048 0 202.048 42.976 271.52 112.48L640.00032 448h384V64l-149.984 149.984A510.272 510.272 0 0 0 512.00032 64C229.21632 64 0.00032 293.216 0.00032 576z"></path></svg>'

// 分割线
export const DIVIDER_SVG =
  '<svg viewBox="0 0 1092 1024"><path d="M0 51.2m51.2 0l989.866667 0q51.2 0 51.2 51.2l0 0q0 51.2-51.2 51.2l-989.866667 0q-51.2 0-51.2-51.2l0 0q0-51.2 51.2-51.2Z"></path><path d="M0 460.8m51.2 0l170.666667 0q51.2 0 51.2 51.2l0 0q0 51.2-51.2 51.2l-170.666667 0q-51.2 0-51.2-51.2l0 0q0-51.2 51.2-51.2Z"></path><path d="M819.2 460.8m51.2 0l170.666667 0q51.2 0 51.2 51.2l0 0q0 51.2-51.2 51.2l-170.666667 0q-51.2 0-51.2-51.2l0 0q0-51.2 51.2-51.2Z"></path><path d="M409.6 460.8m51.2 0l170.666667 0q51.2 0 51.2 51.2l0 0q0 51.2-51.2 51.2l-170.666667 0q-51.2 0-51.2-51.2l0 0q0-51.2 51.2-51.2Z"></path><path d="M0 870.4m51.2 0l989.866667 0q51.2 0 51.2 51.2l0 0q0 51.2-51.2 51.2l-989.866667 0q-51.2 0-51.2-51.2l0 0q0-51.2 51.2-51.2Z"></path></svg>'

// 代码块
export const CODE_BLOCK_SVG =
  '<svg viewBox="0 0 1280 1024"><path d="M832 736l96 96 320-320L928 192l-96 96 224 224zM448 288l-96-96L32 512l320 320 96-96-224-224zM701.312 150.528l69.472 18.944-192 704.032-69.472-18.944 192-704.032z"></path></svg>'

// 全屏
export const FULL_SCREEN_SVG =
  '<svg viewBox="0 0 1024 1024"><path d="M133.705143 335.433143V133.851429h201.581714a29.622857 29.622857 0 0 0 29.622857-29.549715V68.754286a29.622857 29.622857 0 0 0-29.622857-29.622857H61.732571A22.893714 22.893714 0 0 0 38.765714 62.025143V335.725714c0 16.310857 13.238857 29.622857 29.622857 29.622857h35.547429a29.842286 29.842286 0 0 0 29.696-29.842285zM690.980571 133.851429h201.581715v201.654857c0 16.310857 13.238857 29.549714 29.622857 29.549714h35.547428a29.622857 29.622857 0 0 0 29.549715-29.549714V61.952a22.893714 22.893714 0 0 0-22.820572-22.893714h-273.554285a29.622857 29.622857 0 0 0-29.549715 29.622857v35.547428c0 16.310857 13.238857 29.696 29.622857 29.696zM335.286857 892.781714H133.705143V691.2a29.622857 29.622857 0 0 0-29.622857-29.622857H68.534857a29.622857 29.622857 0 0 0-29.549714 29.622857v273.554286c0 12.653714 10.24 22.893714 22.820571 22.893714h273.554286a29.622857 29.622857 0 0 0 29.696-29.622857v-35.547429a29.769143 29.769143 0 0 0-29.769143-29.696z m557.348572-201.581714v201.581714H690.907429a29.622857 29.622857 0 0 0-29.622858 29.622857v35.547429c0 16.310857 13.238857 29.622857 29.622858 29.622857h273.554285c12.580571 0 22.893714-10.313143 22.893715-22.893714V691.2a29.622857 29.622857 0 0 0-29.622858-29.622857h-35.547428a29.622857 29.622857 0 0 0-29.696 29.622857z"></path></svg>'

// 上标
export const SUP_SVG =
  '<svg viewBox="0 0 1024 1024"><path d="M768 206.016v50.016h128v64h-192V174.016l128-60V64h-128V0h192v146.016zM676 256h-136L352 444 164 256H28l256 256-256 256h136L352 580 540 768h136l-256-256z"></path></svg>'

// 下标
export const SUB_SVG =
  '<svg viewBox="0 0 1024 1024"><path d="M768 910.016v50.016h128v64h-192v-146.016l128-60V768h-128v-64h192v146.016zM676 256h-136L352 444 164 256H28l256 256-256 256h136L352 580 540 768h136l-256-256z"></path></svg>'

// checkbox
export const CHECK_BOX_SVG =
  '<svg viewBox="0 0 1024 1024"><path d="M278.755556 403.911111l-79.644445 79.644445L455.111111 739.555556l568.888889-568.888889-79.644444-79.644445L455.111111 580.266667l-176.355555-176.355556zM910.222222 910.222222H113.777778V113.777778h568.888889V0H113.777778C51.2 0 0 51.2 0 113.777778v796.444444c0 62.577778 51.2 113.777778 113.777778 113.777778h796.444444c62.577778 0 113.777778-51.2 113.777778-113.777778V455.111111h-113.777778v455.111111z"></path></svg>'

// 回车
export const ENTER_SVG =
  '<svg viewBox="0 0 1255 1024"><path d="M1095.111111 731.477333h-625.777778V1024L0 658.318222 469.333333 292.408889v292.636444h625.777778V0h156.444445v731.477333z"></path></svg>'


================================================
FILE: packages/basic-modules/src/index.ts
================================================
/**
 * @description basic index
 * @author wangfupeng
 */

import './assets/index.less'

// 配置多语言
import './locale/index'

import wangEditorParagraphModule from './modules/paragraph'
import wangEditorTextStyleModule from './modules/text-style'
import wangEditorHeaderModule from './modules/header'
import wangEditorColorModule from './modules/color'
import wangEditorLinkModule from './modules/link'
import wangEditorImageModule from './modules/image'
import wangEditorTodoModule from './modules/todo'
import wangEditorBlockQuoteModule from './modules/blockquote'
import wangEditorEmotionModule from './modules/emotion'
import wangEditorFontSizeAndFamilyModule from './modules/font-size-family'
import wangEditorIndentModule from './modules/indent'
import wangEditorJustifyModule from './modules/justify'
import wangEditorLineHeightModule from './modules/line-height'
import wangEditorUndoRedoModule from './modules/undo-redo'
import wangEditorDividerModule from './modules/divider'
import wangEditorCodeBlockModule from './modules/code-block'
import wangEditorFullScreenModule from './modules/full-screen'
import wangEditorCommonModule from './modules/common'

export default [
  // text style
  wangEditorTextStyleModule,
  wangEditorColorModule,
  wangEditorFontSizeAndFamilyModule,

  // elem style
  wangEditorIndentModule,
  wangEditorJustifyModule,
  wangEditorLineHeightModule,

  // void node
  wangEditorImageModule,
  wangEditorDividerModule,

  // inline node
  wangEditorEmotionModule,
  wangEditorLinkModule,

  // block node —— 【注意】要放在 void-node 和 inline-node 后面!!!
  wangEditorCodeBlockModule,
  wangEditorBlockQuoteModule,
  wangEditorHeaderModule,
  wangEditorParagraphModule,
  wangEditorTodoModule,

  // command
  wangEditorUndoRedoModule,
  wangEditorFullScreenModule,
  wangEditorCommonModule,
]

// 输出 image 操作,供 updateImageModule 使用
export * from './modules/image/helper'


================================================
FILE: packages/basic-modules/src/locale/en.ts
================================================
/**
 * @description i18n en
 * @author wangfupeng
 */

export default {
  // 通用的词
  common: {
    ok: 'OK',
    delete: 'Delete',
    enter: 'Enter',
  },

  blockQuote: {
    title: 'Quote',
  },
  codeBlock: {
    title: 'Code block',
  },
  color: {
    color: 'Font color',
    bgColor: 'Back color',
    default: 'Default color',
    clear: 'Clear back color',
  },
  divider: {
    title: 'Divider',
  },
  emotion: {
    title: 'Emotion',
  },
  fontSize: {
    title: 'Font size',
    default: 'Default',
  },
  fontFamily: {
    title: 'Font family',
    default: 'Default',
  },
  fullScreen: {
    title: 'Full screen',
  },
  header: {
    title: 'Header',
    text: 'Text',
  },
  image: {
    netImage: 'Net image',
    delete: 'Delete image',
    edit: 'Edit image',
    viewLink: 'View link',
    src: 'Image src',
    desc: 'Description',
    link: 'Image link',
  },
  indent: {
    decrease: 'Decrease',
    increase: 'Increase',
  },
  justify: {
    left: 'Left',
    right: 'Right',
    center: 'Center',
    justify: 'Justify',
  },
  lineHeight: {
    title: 'Line height',
    default: 'Default',
  },
  link: {
    insert: 'Insert link',
    text: 'Link text',
    url: 'Link source',
    unLink: 'Unlink',
    edit: 'Edit link',
    view: 'View link',
  },
  textStyle: {
    bold: 'Bold',
    clear: 'Clear styles',
    code: 'Inline code',
    italic: 'Italic',
    sub: 'Sub',
    sup: 'Sup',
    through: 'Through',
    underline: 'Underline',
  },
  undo: {
    undo: 'undo',
    redo: 'Redo',
  },
  todo: {
    todo: 'Todo',
  },
}


================================================
FILE: packages/basic-modules/src/locale/index.ts
================================================
/**
 * @description i18n entry
 * @author wangfupeng
 */

import { i18nAddResources } from '@wangeditor/core'
import enResources from './en'
import zhResources from './zh-CN'

i18nAddResources('en', enResources)
i18nAddResources('zh-CN', zhResources)


================================================
FILE: packages/basic-modules/src/locale/zh-CN.ts
================================================
/**
 * @description i18n zh-CN
 * @author wangfupeng
 */

export default {
  // 通用的词
  common: {
    ok: '确定',
    delete: '删除',
    enter: '回车',
  },

  blockQuote: {
    title: '引用',
  },
  codeBlock: {
    title: '代码块',
  },
  color: {
    color: '文字颜色',
    bgColor: '背景色',
    default: '默认颜色',
    clear: '清除背景色',
  },
  divider: {
    title: '分割线',
  },
  emotion: {
    title: '表情',
  },
  fontSize: {
    title: '字号',
    default: '默认字号',
  },
  fontFamily: {
    title: '字体',
    default: '默认字体',
  },
  fullScreen: {
    title: '全屏',
  },
  header: {
    title: '标题',
    text: '正文',
  },
  image: {
    netImage: '网络图片',
    delete: '删除图片',
    edit: '编辑图片',
    viewLink: '查看链接',
    src: '图片地址',
    desc: '图片描述',
    link: '图片链接',
  },
  indent: {
    decrease: '减少缩进',
    increase: '增加缩进',
  },
  justify: {
    left: '左对齐',
    right: '右对齐',
    center: '居中对齐',
    justify: '两端对齐',
  },
  lineHeight: {
    title: '行高',
    default: '默认行高',
  },
  link: {
    insert: '插入链接',
    text: '链接文本',
    url: '链接地址',
    unLink: '取消链接',
    edit: '修改链接',
    view: '查看链接',
  },
  textStyle: {
    bold: '粗体',
    clear: '清除格式',
    code: '行内代码',
    italic: '斜体',
    sub: '下标',
    sup: '上标',
    through: '删除线',
    underline: '下划线',
  },
  undo: {
    undo: '撤销',
    redo: '重做',
  },
  todo: {
    todo: '待办',
  },
}


================================================
FILE: packages/basic-modules/src/modules/blockquote/custom-types.ts
================================================
/**
 * @description 自定义 element
 * @author wangfupeng
 */

import { Text } from 'slate'

//【注意】需要把自定义的 Element 引入到最外层的 cus
Download .txt
gitextract_27463ctz/

├── .browserslistrc
├── .cz-config.js
├── .eslintignore
├── .eslintrc.js
├── .github/
│   ├── FUNDING.yml
│   ├── ISSUE_TEMPLATE/
│   │   ├── bug.md
│   │   ├── feature.md
│   │   └── question.md
│   └── workflows/
│       ├── deploy-demos.yml
│       ├── deploy-examples.yml.bak
│       ├── e2e.yml
│       ├── release.yml
│       └── test.yml
├── .gitignore
├── .npmignore
├── .prettierrc.js
├── .vscode/
│   └── settings.json
├── .yarnrc
├── CHANGELOG.md
├── LICENSE
├── README-en.md
├── README.md
├── babel.config.json
├── build/
│   ├── build-all.sh
│   ├── config/
│   │   ├── common.js
│   │   ├── dev.js
│   │   └── prd.js
│   └── create-rollup-config.js
├── commitlint.config.js
├── cypress/
│   ├── cypress.d.ts
│   ├── fixtures/
│   │   └── example.json
│   ├── integration/
│   │   └── editor.spec.ts
│   ├── plugins/
│   │   └── index.ts
│   ├── support/
│   │   ├── commands.ts
│   │   └── index.ts
│   └── tsconfig.json
├── cypress.json
├── docs/
│   ├── README.md
│   ├── dev.md
│   ├── join.md
│   ├── publish.md
│   └── test.md
├── jest.config.js
├── lerna.json
├── package.json
├── packages/
│   ├── basic-modules/
│   │   ├── CHANGELOG.md
│   │   ├── README.md
│   │   ├── __tests__/
│   │   │   ├── blockquote/
│   │   │   │   ├── blockquote-menu.test.ts
│   │   │   │   ├── elem-to-html.test.ts
│   │   │   │   ├── parse-html.test.ts
│   │   │   │   ├── plugin.test.ts
│   │   │   │   └── render-elem.test.ts
│   │   │   ├── code-block/
│   │   │   │   ├── code-block-menu.test.ts
│   │   │   │   ├── elem-to-html.test.ts
│   │   │   │   ├── parse-html.test.ts
│   │   │   │   ├── plugin.test.ts
│   │   │   │   └── render-elem.test.ts
│   │   │   ├── color/
│   │   │   │   ├── color-menus.test.ts
│   │   │   │   ├── parse-html.test.ts
│   │   │   │   ├── render-text-style.test.tsx
│   │   │   │   └── text-style-to-html.test.ts
│   │   │   ├── divider/
│   │   │   │   ├── elem-to-html.test.ts
│   │   │   │   ├── insert-divider-menu.test.ts
│   │   │   │   ├── parse-html.test.ts
│   │   │   │   ├── plugin.test.ts
│   │   │   │   └── render-elem.test.ts
│   │   │   ├── emotion/
│   │   │   │   └── emotion-menu.test.ts
│   │   │   ├── font-size-family/
│   │   │   │   ├── menu/
│   │   │   │   │   ├── font-family-menu.test.ts
│   │   │   │   │   └── font-size-menu.test.ts
│   │   │   │   ├── parse-html.test.ts
│   │   │   │   ├── render-text-style.test.tsx
│   │   │   │   └── text-style-to-html.test.ts
│   │   │   ├── full-screen/
│   │   │   │   └── full-screen-menu.test.ts
│   │   │   ├── header/
│   │   │   │   ├── elem-to-html.test.ts
│   │   │   │   ├── helper.test.ts
│   │   │   │   ├── menu/
│   │   │   │   │   ├── header-select-menu.test.ts
│   │   │   │   │   └── header1-menu.test.ts
│   │   │   │   ├── parse-html.test.ts
│   │   │   │   ├── plugin.test.ts
│   │   │   │   └── render-elem.test.ts
│   │   │   ├── image/
│   │   │   │   ├── elem-to-html.test.ts
│   │   │   │   ├── helper.test.ts
│   │   │   │   ├── menu/
│   │   │   │   │   ├── del-image.test.ts
│   │   │   │   │   ├── edit-image.test.ts
│   │   │   │   │   ├── insert-image.test.ts
│   │   │   │   │   ├── view-image-link.test.ts
│   │   │   │   │   └── width-menus.test.ts
│   │   │   │   ├── parse-html.test.ts
│   │   │   │   ├── plugin.test.ts
│   │   │   │   └── render-elem.test.ts
│   │   │   ├── indent/
│   │   │   │   ├── menu/
│   │   │   │   │   ├── decrease-indent-menu.test.ts
│   │   │   │   │   └── increase-indent-menu.test.ts
│   │   │   │   ├── parse-html.test.ts
│   │   │   │   ├── render-text-style.test.tsx
│   │   │   │   └── text-style-to-html.test.ts
│   │   │   ├── justify/
│   │   │   │   ├── menus.test.ts
│   │   │   │   ├── parse-html.test.ts
│   │   │   │   ├── render-text-style.test.tsx
│   │   │   │   └── text-style-to-html.test.ts
│   │   │   ├── line-height/
│   │   │   │   ├── line-height-menu.test.ts
│   │   │   │   ├── parse-html.test.ts
│   │   │   │   ├── render-text-style.test.tsx
│   │   │   │   └── text-style-to-html.test.ts
│   │   │   ├── link/
│   │   │   │   ├── elem-to-html.test.ts
│   │   │   │   ├── helper.test.ts
│   │   │   │   ├── menu/
│   │   │   │   │   ├── edit-link-menu.test.ts
│   │   │   │   │   ├── insert-link-menu.test.ts
│   │   │   │   │   ├── unlink-menu.test.ts
│   │   │   │   │   └── view-link-menu.test.ts
│   │   │   │   ├── parse-html.test.ts
│   │   │   │   ├── plugin.test.ts
│   │   │   │   └── render-elem.test.ts
│   │   │   ├── paragraph/
│   │   │   │   ├── elem-to-html.test.ts
│   │   │   │   ├── parse-html.test.ts
│   │   │   │   ├── plugin.test.ts
│   │   │   │   └── render-elem.test.ts
│   │   │   ├── text-style/
│   │   │   │   ├── menu/
│   │   │   │   │   ├── clear-style-menu.test.ts
│   │   │   │   │   └── menus.test.ts
│   │   │   │   ├── parse-html.test.ts
│   │   │   │   ├── parse-style-html.test.ts
│   │   │   │   ├── text-style.test.tsx
│   │   │   │   └── text-to-html.test.ts
│   │   │   ├── todo/
│   │   │   │   ├── elem-to-html.test.ts
│   │   │   │   ├── menu/
│   │   │   │   │   └── todo-menu.test.ts
│   │   │   │   ├── parse-html.test.ts
│   │   │   │   ├── plugin.test.ts
│   │   │   │   ├── pre-parse-html.test.ts
│   │   │   │   └── render-elem.test.ts
│   │   │   └── undo-redo/
│   │   │       ├── redo-menu.test.ts
│   │   │       └── undo-menu.test.ts
│   │   ├── package.json
│   │   ├── rollup.config.js
│   │   ├── src/
│   │   │   ├── assets/
│   │   │   │   ├── blockquote.less
│   │   │   │   ├── code-block.less
│   │   │   │   ├── color.less
│   │   │   │   ├── divider.less
│   │   │   │   ├── emotion.less
│   │   │   │   ├── image.less
│   │   │   │   ├── index.less
│   │   │   │   └── simple-style.less
│   │   │   ├── constants/
│   │   │   │   └── icon-svg.ts
│   │   │   ├── index.ts
│   │   │   ├── locale/
│   │   │   │   ├── en.ts
│   │   │   │   ├── index.ts
│   │   │   │   └── zh-CN.ts
│   │   │   ├── modules/
│   │   │   │   ├── blockquote/
│   │   │   │   │   ├── custom-types.ts
│   │   │   │   │   ├── elem-to-html.ts
│   │   │   │   │   ├── index.ts
│   │   │   │   │   ├── menu/
│   │   │   │   │   │   ├── BlockquoteMenu.ts
│   │   │   │   │   │   └── index.ts
│   │   │   │   │   ├── parse-elem-html.ts
│   │   │   │   │   ├── plugin.ts
│   │   │   │   │   └── render-elem.tsx
│   │   │   │   ├── code-block/
│   │   │   │   │   ├── custom-types.ts
│   │   │   │   │   ├── elem-to-html.ts
│   │   │   │   │   ├── index.ts
│   │   │   │   │   ├── menu/
│   │   │   │   │   │   ├── CodeBlockMenu.ts
│   │   │   │   │   │   └── index.ts
│   │   │   │   │   ├── parse-elem-html.ts
│   │   │   │   │   ├── plugin.ts
│   │   │   │   │   ├── pre-parse-html.ts
│   │   │   │   │   └── render-elem.tsx
│   │   │   │   ├── color/
│   │   │   │   │   ├── custom-types.ts
│   │   │   │   │   ├── index.ts
│   │   │   │   │   ├── menu/
│   │   │   │   │   │   ├── BaseMenu.ts
│   │   │   │   │   │   ├── BgColorMenu.ts
│   │   │   │   │   │   ├── ColorMenu.ts
│   │   │   │   │   │   ├── config.ts
│   │   │   │   │   │   └── index.ts
│   │   │   │   │   ├── parse-style-html.ts
│   │   │   │   │   ├── pre-parse-html.ts
│   │   │   │   │   ├── render-style.tsx
│   │   │   │   │   └── style-to-html.ts
│   │   │   │   ├── common/
│   │   │   │   │   ├── index.ts
│   │   │   │   │   └── menu/
│   │   │   │   │       ├── EnterMenu.ts
│   │   │   │   │       └── index.ts
│   │   │   │   ├── divider/
│   │   │   │   │   ├── README.md
│   │   │   │   │   ├── custom-types.ts
│   │   │   │   │   ├── elem-to-html.ts
│   │   │   │   │   ├── index.ts
│   │   │   │   │   ├── menu/
│   │   │   │   │   │   ├── DeleteDividerMenu.ts.bak
│   │   │   │   │   │   ├── InsertDividerMenu.ts
│   │   │   │   │   │   └── index.ts
│   │   │   │   │   ├── parse-elem-html.ts
│   │   │   │   │   ├── plugin.ts
│   │   │   │   │   └── render-elem.tsx
│   │   │   │   ├── emotion/
│   │   │   │   │   ├── index.ts
│   │   │   │   │   └── menu/
│   │   │   │   │       ├── EmotionMenu.ts
│   │   │   │   │       ├── config.ts
│   │   │   │   │       └── index.ts
│   │   │   │   ├── font-size-family/
│   │   │   │   │   ├── custom-types.ts
│   │   │   │   │   ├── index.ts
│   │   │   │   │   ├── menu/
│   │   │   │   │   │   ├── BaseMenu.ts
│   │   │   │   │   │   ├── FontFamilyMenu.ts
│   │   │   │   │   │   ├── FontSizeMenu.ts
│   │   │   │   │   │   ├── config.ts
│   │   │   │   │   │   └── index.ts
│   │   │   │   │   ├── parse-style-html.ts
│   │   │   │   │   ├── pre-parse-html.ts
│   │   │   │   │   ├── render-style.tsx
│   │   │   │   │   └── style-to-html.ts
│   │   │   │   ├── full-screen/
│   │   │   │   │   ├── index.ts
│   │   │   │   │   └── menu/
│   │   │   │   │       ├── FullScreen.ts
│   │   │   │   │       └── index.ts
│   │   │   │   ├── header/
│   │   │   │   │   ├── custom-types.ts
│   │   │   │   │   ├── elem-to-html.ts
│   │   │   │   │   ├── helper.ts
│   │   │   │   │   ├── index.ts
│   │   │   │   │   ├── menu/
│   │   │   │   │   │   ├── Header1ButtonMenu.ts
│   │   │   │   │   │   ├── Header2ButtonMenu.ts
│   │   │   │   │   │   ├── Header3ButtonMenu.ts
│   │   │   │   │   │   ├── Header4ButtonMenu.ts
│   │   │   │   │   │   ├── Header5ButtonMenu.ts
│   │   │   │   │   │   ├── HeaderButtonMenuBase.ts
│   │   │   │   │   │   ├── HeaderSelectMenu.ts
│   │   │   │   │   │   └── index.ts
│   │   │   │   │   ├── parse-elem-html.ts
│   │   │   │   │   ├── plugin.ts
│   │   │   │   │   └── render-elem.tsx
│   │   │   │   ├── image/
│   │   │   │   │   ├── custom-types.ts
│   │   │   │   │   ├── elem-to-html.ts
│   │   │   │   │   ├── helper.ts
│   │   │   │   │   ├── index.ts
│   │   │   │   │   ├── menu/
│   │   │   │   │   │   ├── DeleteImage.ts
│   │   │   │   │   │   ├── EditImage.ts
│   │   │   │   │   │   ├── InsertImage.ts
│   │   │   │   │   │   ├── ViewImageLink.ts
│   │   │   │   │   │   ├── Width100.ts
│   │   │   │   │   │   ├── Width30.ts
│   │   │   │   │   │   ├── Width50.ts
│   │   │   │   │   │   ├── WidthBase.ts
│   │   │   │   │   │   ├── config.ts
│   │   │   │   │   │   └── index.ts
│   │   │   │   │   ├── parse-elem-html.ts
│   │   │   │   │   ├── plugin.ts
│   │   │   │   │   └── render-elem.tsx
│   │   │   │   ├── indent/
│   │   │   │   │   ├── custom-types.ts
│   │   │   │   │   ├── index.ts
│   │   │   │   │   ├── menu/
│   │   │   │   │   │   ├── BaseMenu.ts
│   │   │   │   │   │   ├── DecreaseIndentMenu.ts
│   │   │   │   │   │   ├── IncreaseIndentMenu.ts
│   │   │   │   │   │   └── index.ts
│   │   │   │   │   ├── parse-style-html.ts
│   │   │   │   │   ├── pre-parse-html.ts
│   │   │   │   │   ├── render-style.tsx
│   │   │   │   │   └── style-to-html.ts
│   │   │   │   ├── justify/
│   │   │   │   │   ├── custom-types.ts
│   │   │   │   │   ├── index.ts
│   │   │   │   │   ├── menu/
│   │   │   │   │   │   ├── BaseMenu.ts
│   │   │   │   │   │   ├── JustifyCenterMenu.ts
│   │   │   │   │   │   ├── JustifyJustifyMenu.ts
│   │   │   │   │   │   ├── JustifyLeftMenu.ts
│   │   │   │   │   │   ├── JustifyRightMenu.ts
│   │   │   │   │   │   └── index.ts
│   │   │   │   │   ├── parse-style-html.ts
│   │   │   │   │   ├── render-style.tsx
│   │   │   │   │   └── style-to-html.ts
│   │   │   │   ├── line-height/
│   │   │   │   │   ├── custom-types.ts
│   │   │   │   │   ├── index.ts
│   │   │   │   │   ├── menu/
│   │   │   │   │   │   ├── LineHeightMenu.ts
│   │   │   │   │   │   ├── config.ts
│   │   │   │   │   │   └── index.ts
│   │   │   │   │   ├── parse-style-html.ts
│   │   │   │   │   ├── render-style.tsx
│   │   │   │   │   └── style-to-html.ts
│   │   │   │   ├── link/
│   │   │   │   │   ├── custom-types.ts
│   │   │   │   │   ├── elem-to-html.ts
│   │   │   │   │   ├── helper.ts
│   │   │   │   │   ├── index.ts
│   │   │   │   │   ├── menu/
│   │   │   │   │   │   ├── EditLink.ts
│   │   │   │   │   │   ├── InsertLink.ts
│   │   │   │   │   │   ├── UnLink.ts
│   │   │   │   │   │   ├── ViewLink.ts
│   │   │   │   │   │   ├── config.ts
│   │   │   │   │   │   └── index.ts
│   │   │   │   │   ├── parse-elem-html.ts
│   │   │   │   │   ├── plugin.ts
│   │   │   │   │   └── render-elem.tsx
│   │   │   │   ├── paragraph/
│   │   │   │   │   ├── custom-types.ts
│   │   │   │   │   ├── elem-to-html.ts
│   │   │   │   │   ├── index.ts
│   │   │   │   │   ├── parse-elem-html.ts
│   │   │   │   │   ├── plugin.ts
│   │   │   │   │   └── render-elem.tsx
│   │   │   │   ├── text-style/
│   │   │   │   │   ├── custom-types.ts
│   │   │   │   │   ├── helper.ts
│   │   │   │   │   ├── index.ts
│   │   │   │   │   ├── menu/
│   │   │   │   │   │   ├── BaseMenu.ts
│   │   │   │   │   │   ├── BoldMenu.ts
│   │   │   │   │   │   ├── ClearStyleMenu.ts
│   │   │   │   │   │   ├── CodeMenu.ts
│   │   │   │   │   │   ├── ItalicMenu.ts
│   │   │   │   │   │   ├── SubMenu.ts
│   │   │   │   │   │   ├── SupMenu.ts
│   │   │   │   │   │   ├── ThroughMenu.ts
│   │   │   │   │   │   ├── UnderlineMenu.ts
│   │   │   │   │   │   └── index.ts
│   │   │   │   │   ├── parse-style-html.ts
│   │   │   │   │   ├── render-style.tsx
│   │   │   │   │   └── style-to-html.ts
│   │   │   │   ├── todo/
│   │   │   │   │   ├── custom-types.ts
│   │   │   │   │   ├── elem-to-html.ts
│   │   │   │   │   ├── index.ts
│   │   │   │   │   ├── menu/
│   │   │   │   │   │   ├── Todo.ts
│   │   │   │   │   │   └── index.ts
│   │   │   │   │   ├── parse-elem-html.ts
│   │   │   │   │   ├── plugin.ts
│   │   │   │   │   ├── pre-parse-html.ts
│   │   │   │   │   └── render-elem.tsx
│   │   │   │   └── undo-redo/
│   │   │   │       ├── index.ts
│   │   │   │       └── menu/
│   │   │   │           ├── RedoMenu.ts
│   │   │   │           ├── UndoMenu.ts
│   │   │   │           └── index.ts
│   │   │   └── utils/
│   │   │       ├── dom.ts
│   │   │       ├── util.ts
│   │   │       └── vdom.ts
│   │   └── tsconfig.json
│   ├── code-highlight/
│   │   ├── CHANGELOG.md
│   │   ├── README.md
│   │   ├── __tests__/
│   │   │   ├── content.ts
│   │   │   ├── decorate.test.ts
│   │   │   ├── elem-to-html.test.ts
│   │   │   ├── parse-html.test.ts
│   │   │   ├── render-text-style.test.tsx
│   │   │   └── select-lang-menu.test.ts
│   │   ├── package.json
│   │   ├── rollup.config.js
│   │   ├── src/
│   │   │   ├── assets/
│   │   │   │   └── index.less
│   │   │   ├── constants/
│   │   │   │   └── svg.ts
│   │   │   ├── custom-types.ts
│   │   │   ├── decorate/
│   │   │   │   └── index.ts
│   │   │   ├── index.ts
│   │   │   ├── locale/
│   │   │   │   ├── en.ts
│   │   │   │   ├── index.ts
│   │   │   │   └── zh-CN.ts
│   │   │   ├── module/
│   │   │   │   ├── elem-to-html.ts
│   │   │   │   ├── index.ts
│   │   │   │   ├── menu/
│   │   │   │   │   ├── SelectLangMenu.ts
│   │   │   │   │   ├── config.ts
│   │   │   │   │   └── index.ts
│   │   │   │   ├── parse-style-html.ts
│   │   │   │   └── render-style.tsx
│   │   │   ├── utils/
│   │   │   │   ├── dom.ts
│   │   │   │   └── vdom.ts
│   │   │   └── vendor/
│   │   │       └── prism.ts
│   │   └── tsconfig.json
│   ├── core/
│   │   ├── CHANGELOG.md
│   │   ├── README.md
│   │   ├── __tests__/
│   │   │   ├── config/
│   │   │   │   ├── editor-config.test.ts
│   │   │   │   ├── menu-config.test.ts
│   │   │   │   └── toolbar-config.test.ts
│   │   │   ├── create/
│   │   │   │   └── content-to-html.test.ts
│   │   │   ├── create-core-editor.ts
│   │   │   ├── editor/
│   │   │   │   ├── dom-editor.test.ts
│   │   │   │   └── plugins/
│   │   │   │       ├── with-config.test.ts
│   │   │   │       ├── with-content.test.ts
│   │   │   │       ├── with-dom.test.ts
│   │   │   │       ├── with-emitter.test.ts
│   │   │   │       └── with-selection.test.ts
│   │   │   ├── i18n/
│   │   │   │   └── index.test.ts
│   │   │   ├── menus/
│   │   │   │   ├── README.md
│   │   │   │   └── register-menus/
│   │   │   │       ├── index.ts
│   │   │   │       ├── register-button-menu.ts
│   │   │   │       ├── register-modal-menu.ts
│   │   │   │       └── register-select-menu.ts
│   │   │   ├── parse-html/
│   │   │   │   └── README.md
│   │   │   ├── render/
│   │   │   │   └── README.md
│   │   │   ├── to-html/
│   │   │   │   └── README.md
│   │   │   ├── upload/
│   │   │   │   └── uploader.test.ts
│   │   │   └── utils/
│   │   │       ├── util.test.ts
│   │   │       └── vdom.test.ts
│   │   ├── package.json
│   │   ├── rollup.config.js
│   │   ├── src/
│   │   │   ├── assets/
│   │   │   │   ├── bar-item.less
│   │   │   │   ├── bar.less
│   │   │   │   ├── common.less
│   │   │   │   ├── drop-panel.less
│   │   │   │   ├── full-screen.less
│   │   │   │   ├── index.less
│   │   │   │   ├── modal.less
│   │   │   │   ├── progress.less
│   │   │   │   ├── select-list.less
│   │   │   │   └── textarea.less
│   │   │   ├── config/
│   │   │   │   ├── index.ts
│   │   │   │   ├── interface.ts
│   │   │   │   └── register.ts
│   │   │   ├── constants/
│   │   │   │   ├── index.ts
│   │   │   │   └── svg.ts
│   │   │   ├── create/
│   │   │   │   ├── bind-node-relation.ts
│   │   │   │   ├── create-editor.ts
│   │   │   │   ├── create-toolbar.ts
│   │   │   │   ├── helper.ts
│   │   │   │   └── index.ts
│   │   │   ├── editor/
│   │   │   │   ├── dom-editor.ts
│   │   │   │   ├── interface.ts
│   │   │   │   └── plugins/
│   │   │   │       ├── with-config.ts
│   │   │   │       ├── with-content.ts
│   │   │   │       ├── with-dom.ts
│   │   │   │       ├── with-emitter.ts
│   │   │   │       ├── with-event-data.ts
│   │   │   │       ├── with-max-length.ts
│   │   │   │       └── with-selection.ts
│   │   │   ├── i18n/
│   │   │   │   └── index.ts
│   │   │   ├── index.ts
│   │   │   ├── menus/
│   │   │   │   ├── README.md
│   │   │   │   ├── bar/
│   │   │   │   │   ├── HoverBar.ts
│   │   │   │   │   └── Toolbar.ts
│   │   │   │   ├── bar-item/
│   │   │   │   │   ├── BaseButton.ts
│   │   │   │   │   ├── DropPanelButton.ts
│   │   │   │   │   ├── GroupButton.ts
│   │   │   │   │   ├── ModalButton.ts
│   │   │   │   │   ├── Select.ts
│   │   │   │   │   ├── SimpleButton.ts
│   │   │   │   │   ├── index.ts
│   │   │   │   │   └── tooltip.ts
│   │   │   │   ├── helpers/
│   │   │   │   │   ├── helpers.ts
│   │   │   │   │   └── position.ts
│   │   │   │   ├── index.ts
│   │   │   │   ├── interface.ts
│   │   │   │   ├── panel-and-modal/
│   │   │   │   │   ├── BaseClass.ts
│   │   │   │   │   ├── DropPanel.ts
│   │   │   │   │   ├── Modal.ts
│   │   │   │   │   └── SelectList.ts
│   │   │   │   └── register.ts
│   │   │   ├── parse-html/
│   │   │   │   ├── README.md
│   │   │   │   ├── helper.ts
│   │   │   │   ├── index.ts
│   │   │   │   ├── parse-common-elem-html.ts
│   │   │   │   ├── parse-elem-html.ts
│   │   │   │   └── parse-text-elem-html.ts
│   │   │   ├── render/
│   │   │   │   ├── README.md
│   │   │   │   ├── element/
│   │   │   │   │   ├── getRenderElem.tsx
│   │   │   │   │   ├── renderElement.tsx
│   │   │   │   │   └── renderStyle.ts
│   │   │   │   ├── helper.ts
│   │   │   │   ├── index.ts
│   │   │   │   ├── node2Vnode.ts
│   │   │   │   └── text/
│   │   │   │       ├── genVnode.tsx
│   │   │   │       ├── renderStyle.ts
│   │   │   │       └── renderText.tsx
│   │   │   ├── text-area/
│   │   │   │   ├── TextArea.ts
│   │   │   │   ├── event-handlers/
│   │   │   │   │   ├── beforeInput.ts
│   │   │   │   │   ├── blur.ts
│   │   │   │   │   ├── click.ts
│   │   │   │   │   ├── composition.ts
│   │   │   │   │   ├── copy.ts
│   │   │   │   │   ├── cut.ts
│   │   │   │   │   ├── drag.ts
│   │   │   │   │   ├── drop.ts
│   │   │   │   │   ├── focus.ts
│   │   │   │   │   ├── index.ts
│   │   │   │   │   ├── keydown.ts
│   │   │   │   │   ├── keypress.ts
│   │   │   │   │   └── paste.ts
│   │   │   │   ├── helpers.ts
│   │   │   │   ├── place-holder.ts
│   │   │   │   ├── syncSelection.ts
│   │   │   │   └── update-view.ts
│   │   │   ├── to-html/
│   │   │   │   ├── README.md
│   │   │   │   ├── elem2html.ts
│   │   │   │   ├── index.ts
│   │   │   │   ├── node2html.ts
│   │   │   │   └── text2html.ts
│   │   │   ├── upload/
│   │   │   │   ├── createUploader.ts
│   │   │   │   ├── index.ts
│   │   │   │   └── interface.ts
│   │   │   └── utils/
│   │   │       ├── dom.ts
│   │   │       ├── hotkeys.ts
│   │   │       ├── key.ts
│   │   │       ├── line.ts
│   │   │       ├── ua.ts
│   │   │       ├── util.ts
│   │   │       ├── vdom.ts
│   │   │       └── weak-maps.ts
│   │   └── tsconfig.json
│   ├── custom-types.d.ts
│   ├── editor/
│   │   ├── CHANGELOG.md
│   │   ├── README-en.md
│   │   ├── README.md
│   │   ├── __tests__/
│   │   │   └── create.test.ts
│   │   ├── demo/
│   │   │   ├── README.md
│   │   │   ├── catalog.html
│   │   │   ├── code-highlight.html
│   │   │   ├── css/
│   │   │   │   ├── layout.css
│   │   │   │   └── view.css
│   │   │   ├── extend-menu-drop-panel.html
│   │   │   ├── extend-menu-modal.html
│   │   │   ├── extend-menu-select.html
│   │   │   ├── extend-menu.html
│   │   │   ├── get-html.html
│   │   │   ├── huge-doc.html
│   │   │   ├── index.html
│   │   │   ├── js/
│   │   │   │   ├── custom-elem.js
│   │   │   │   └── huge-content.js
│   │   │   ├── like-qq-doc.html
│   │   │   ├── max-length.html
│   │   │   ├── multi-editor.html
│   │   │   ├── set-html.html
│   │   │   └── simple-mode.html
│   │   ├── examples/
│   │   │   ├── README.md
│   │   │   ├── batch-destroy.html
│   │   │   ├── check.html
│   │   │   ├── code-highlight.html
│   │   │   ├── content-to-html.html
│   │   │   ├── css/
│   │   │   │   ├── editor.css
│   │   │   │   └── view.css
│   │   │   ├── default-mode.html
│   │   │   ├── dom7-demo.html
│   │   │   ├── headers.html
│   │   │   ├── huge-doc.html
│   │   │   ├── i18n.html
│   │   │   ├── index.html
│   │   │   ├── js/
│   │   │   │   ├── huge-content.js
│   │   │   │   └── init-content.js
│   │   │   ├── like-yuque.html
│   │   │   ├── maxlength.html
│   │   │   ├── menu.html
│   │   │   ├── modal-appendTo-body.html
│   │   │   ├── multi-editors.html
│   │   │   ├── new-menu.html
│   │   │   ├── parse-html.html
│   │   │   ├── shadow-dom.html
│   │   │   ├── simple-mode.html
│   │   │   ├── theme.html
│   │   │   ├── todo.html
│   │   │   ├── upload-image.html
│   │   │   └── upload-video.html
│   │   ├── package.json
│   │   ├── rollup.config.js
│   │   ├── src/
│   │   │   ├── Boot.ts
│   │   │   ├── assets/
│   │   │   │   └── index.less
│   │   │   ├── constants/
│   │   │   │   └── svg.ts
│   │   │   ├── create.ts
│   │   │   ├── index.ts
│   │   │   ├── init-default-config/
│   │   │   │   ├── config/
│   │   │   │   │   ├── hoverbar.ts
│   │   │   │   │   ├── index.ts
│   │   │   │   │   └── toolbar.ts
│   │   │   │   └── index.ts
│   │   │   ├── locale/
│   │   │   │   ├── en.ts
│   │   │   │   ├── index.ts
│   │   │   │   └── zh-CN.ts
│   │   │   ├── register-builtin-modules/
│   │   │   │   ├── index.ts
│   │   │   │   └── register.ts
│   │   │   └── utils/
│   │   │       ├── browser-polyfill.ts
│   │   │       ├── dom.ts
│   │   │       └── node-polyfill.ts
│   │   └── tsconfig.json
│   ├── list-module/
│   │   ├── CHANGELOG.md
│   │   ├── README.md
│   │   ├── __tests__/
│   │   │   ├── elem-to-html.test.ts
│   │   │   ├── menu/
│   │   │   │   ├── bulleted-list-menu.test.ts
│   │   │   │   └── numbered-list-menu.test.ts
│   │   │   ├── parse-html.test.ts
│   │   │   ├── plugin.test.ts
│   │   │   └── render-elem.test.ts
│   │   ├── package.json
│   │   ├── rollup.config.js
│   │   ├── src/
│   │   │   ├── assets/
│   │   │   │   └── index.less
│   │   │   ├── constants/
│   │   │   │   └── svg.ts
│   │   │   ├── index.ts
│   │   │   ├── locale/
│   │   │   │   ├── en.ts
│   │   │   │   ├── index.ts
│   │   │   │   └── zh-CN.ts
│   │   │   ├── module/
│   │   │   │   ├── custom-types.ts
│   │   │   │   ├── elem-to-html.ts
│   │   │   │   ├── index.ts
│   │   │   │   ├── menu/
│   │   │   │   │   ├── BaseMenu.ts
│   │   │   │   │   ├── BulletedListMenu.ts
│   │   │   │   │   ├── NumberedListMenu.ts
│   │   │   │   │   └── index.ts
│   │   │   │   ├── parse-elem-html.ts
│   │   │   │   ├── plugin.ts
│   │   │   │   └── render-elem.tsx
│   │   │   └── utils/
│   │   │       ├── dom.ts
│   │   │       └── maps.ts
│   │   └── tsconfig.json
│   ├── table-module/
│   │   ├── CHANGELOG.md
│   │   ├── README.md
│   │   ├── __tests__/
│   │   │   ├── elem-to-html.test.ts
│   │   │   ├── menu/
│   │   │   │   ├── delete-col.test.ts
│   │   │   │   ├── delete-row.test.ts
│   │   │   │   ├── delete-table.test.ts
│   │   │   │   ├── full-width.test.ts
│   │   │   │   ├── insert-col.test.ts
│   │   │   │   ├── insert-row.test.ts
│   │   │   │   ├── insert-table.test.ts
│   │   │   │   └── table-header.test.ts
│   │   │   ├── parse-html.test.ts
│   │   │   ├── plugin.test.ts
│   │   │   └── render-elem.test.ts
│   │   ├── package.json
│   │   ├── rollup.config.js
│   │   ├── src/
│   │   │   ├── assets/
│   │   │   │   └── index.less
│   │   │   ├── constants/
│   │   │   │   └── svg.ts
│   │   │   ├── index.ts
│   │   │   ├── locale/
│   │   │   │   ├── en.ts
│   │   │   │   ├── index.ts
│   │   │   │   └── zh-CN.ts
│   │   │   ├── module/
│   │   │   │   ├── custom-types.ts
│   │   │   │   ├── elem-to-html.ts
│   │   │   │   ├── helpers.ts
│   │   │   │   ├── index.ts
│   │   │   │   ├── menu/
│   │   │   │   │   ├── DeleteCol.ts
│   │   │   │   │   ├── DeleteRow.ts
│   │   │   │   │   ├── DeleteTable.ts
│   │   │   │   │   ├── FullWidth.ts
│   │   │   │   │   ├── InsertCol.ts
│   │   │   │   │   ├── InsertRow.ts
│   │   │   │   │   ├── InsertTable.ts
│   │   │   │   │   ├── TableHeader.ts
│   │   │   │   │   └── index.ts
│   │   │   │   ├── parse-elem-html.ts
│   │   │   │   ├── plugin.ts
│   │   │   │   ├── pre-parse-html.ts
│   │   │   │   └── render-elem/
│   │   │   │       ├── index.ts
│   │   │   │       ├── render-cell.tsx
│   │   │   │       ├── render-row.tsx
│   │   │   │       └── render-table.tsx
│   │   │   └── utils/
│   │   │       ├── dom.ts
│   │   │       └── util.ts
│   │   └── tsconfig.json
│   ├── upload-image-module/
│   │   ├── CHANGELOG.md
│   │   ├── README.md
│   │   ├── __tests__/
│   │   │   ├── config.test.ts
│   │   │   ├── plugin.test.ts
│   │   │   ├── upload-files.test.ts
│   │   │   └── upload-image-menu.test.ts
│   │   ├── package.json
│   │   ├── rollup.config.js
│   │   ├── src/
│   │   │   ├── assets/
│   │   │   │   └── index.less
│   │   │   ├── constants/
│   │   │   │   └── svg.ts
│   │   │   ├── index.ts
│   │   │   ├── locale/
│   │   │   │   ├── en.ts
│   │   │   │   ├── index.ts
│   │   │   │   └── zh-CN.ts
│   │   │   ├── module/
│   │   │   │   ├── index.ts
│   │   │   │   ├── menu/
│   │   │   │   │   ├── UploadImageMenu.ts
│   │   │   │   │   ├── config.ts
│   │   │   │   │   └── index.ts
│   │   │   │   ├── plugin.ts
│   │   │   │   └── upload-images.ts
│   │   │   └── utils/
│   │   │       └── dom.ts
│   │   └── tsconfig.json
│   ├── vars.less
│   └── video-module/
│       ├── CHANGELOG.md
│       ├── README.md
│       ├── __tests__/
│       │   ├── elem-to-html.test.ts
│       │   ├── helpler.test.ts
│       │   ├── menu/
│       │   │   ├── delete-video-menu.test.ts.bak
│       │   │   ├── insert-video-menu.test.ts
│       │   │   └── upload-video-menu.test.ts
│       │   ├── parse-html.test.ts
│       │   ├── plugin.test.ts
│       │   ├── render-elem.test.ts
│       │   └── util.test.ts
│       ├── package.json
│       ├── rollup.config.js
│       ├── src/
│       │   ├── assets/
│       │   │   └── index.less
│       │   ├── constants/
│       │   │   └── svg.ts
│       │   ├── index.ts
│       │   ├── locale/
│       │   │   ├── en.ts
│       │   │   ├── index.ts
│       │   │   └── zh-CN.ts
│       │   ├── module/
│       │   │   ├── custom-types.ts
│       │   │   ├── elem-to-html.ts
│       │   │   ├── helper/
│       │   │   │   ├── insert-video.ts
│       │   │   │   └── upload-videos.ts
│       │   │   ├── index.ts
│       │   │   ├── menu/
│       │   │   │   ├── DeleteVideoMenu.ts.bak
│       │   │   │   ├── EditVideoSizeMenu.ts
│       │   │   │   ├── InsertVideoMenu.ts
│       │   │   │   ├── UploadVideoMenu.ts
│       │   │   │   ├── config.ts
│       │   │   │   └── index.ts
│       │   │   ├── parse-elem-html.ts
│       │   │   ├── plugin.ts
│       │   │   ├── pre-parse-html.ts
│       │   │   └── render-elem.tsx
│       │   └── utils/
│       │       ├── dom.ts
│       │       └── util.ts
│       └── tsconfig.json
├── scripts/
│   └── release-tag.js
├── tests/
│   ├── setup/
│   │   └── index.ts
│   └── utils/
│       ├── create-editor.ts
│       ├── create-toolbar.ts
│       └── stylesMock.js
└── tsconfig.json
Download .txt
SYMBOL INDEX (1055 symbols across 341 files)

FILE: build/config/common.js
  function genCommonConf (line 23) | function genCommonConf(format) {

FILE: build/config/dev.js
  function genDevConf (line 14) | function genDevConf(format) {

FILE: build/config/prd.js
  function genPrdConf (line 19) | function genPrdConf(format) {

FILE: build/create-rollup-config.js
  constant ENV (line 12) | const ENV = process.env.NODE_ENV || 'production'
  constant IS_SIZE_STATS (line 13) | const IS_SIZE_STATS = ENV.indexOf('size_stats') >= 0 // 分析包体积
  constant IS_DEV (line 14) | const IS_DEV = ENV.indexOf('development') >= 0
  constant IS_PRD (line 15) | const IS_PRD = ENV.indexOf('production') >= 0
  function createRollupConfig (line 21) | function createRollupConfig(customConfig = {}) {

FILE: cypress/cypress.d.ts
  type CustomWindow (line 4) | interface CustomWindow extends Window {}
  type Chainable (line 6) | interface Chainable {

FILE: packages/basic-modules/__tests__/code-block/plugin.test.ts
  class MyDataTransfer (line 11) | class MyDataTransfer {
    method setData (line 13) | setData(type: string, value: string) {
    method getData (line 16) | getData(type: string): string {

FILE: packages/basic-modules/__tests__/link/plugin.test.ts
  class MyDataTransfer (line 11) | class MyDataTransfer {
    method setData (line 13) | setData(type: string, value: string) {
    method getData (line 16) | getData(type: string): string {

FILE: packages/basic-modules/__tests__/text-style/menu/menus.test.ts
  constant MENU_INFO_LIST (line 16) | const MENU_INFO_LIST = [

FILE: packages/basic-modules/src/constants/icon-svg.ts
  constant BOLD_SVG (line 13) | const BOLD_SVG =
  constant UNDER_LINE_SVG (line 17) | const UNDER_LINE_SVG =
  constant ITALIC_SVG (line 21) | const ITALIC_SVG =
  constant THROUGH_SVG (line 25) | const THROUGH_SVG =
  constant CODE_SVG (line 29) | const CODE_SVG =
  constant ERASER_SVG (line 33) | const ERASER_SVG =
  constant LINK_SVG (line 37) | const LINK_SVG =
  constant UN_LINK_SVG (line 41) | const UN_LINK_SVG =
  constant PENCIL_SVG (line 45) | const PENCIL_SVG =
  constant EXTERNAL_SVG (line 49) | const EXTERNAL_SVG =
  constant HEADER_SVG (line 53) | const HEADER_SVG =
  constant FONT_COLOR_SVG (line 57) | const FONT_COLOR_SVG =
  constant BG_COLOR_SVG (line 61) | const BG_COLOR_SVG =
  constant CLEAN_SVG (line 65) | const CLEAN_SVG =
  constant IMAGE_SVG (line 69) | const IMAGE_SVG =
  constant TRASH_SVG (line 73) | const TRASH_SVG =
  constant QUOTE_SVG (line 77) | const QUOTE_SVG =
  constant EMOTION_SVG (line 81) | const EMOTION_SVG =
  constant FONT_SIZE_SVG (line 85) | const FONT_SIZE_SVG =
  constant FONT_FAMILY_SVG (line 89) | const FONT_FAMILY_SVG =
  constant INDENT_LEFT_SVG (line 93) | const INDENT_LEFT_SVG =
  constant INDENT_RIGHT_SVG (line 97) | const INDENT_RIGHT_SVG =
  constant JUSTIFY_LEFT_SVG (line 101) | const JUSTIFY_LEFT_SVG =
  constant JUSTIFY_RIGHT_SVG (line 105) | const JUSTIFY_RIGHT_SVG =
  constant JUSTIFY_CENTER_SVG (line 109) | const JUSTIFY_CENTER_SVG =
  constant JUSTIFY_JUSTIFY_SVG (line 113) | const JUSTIFY_JUSTIFY_SVG =
  constant LINE_HEIGHT_SVG (line 117) | const LINE_HEIGHT_SVG =
  constant UNDO_SVG (line 121) | const UNDO_SVG =
  constant REDO_SVG (line 125) | const REDO_SVG =
  constant DIVIDER_SVG (line 129) | const DIVIDER_SVG =
  constant CODE_BLOCK_SVG (line 133) | const CODE_BLOCK_SVG =
  constant FULL_SCREEN_SVG (line 137) | const FULL_SCREEN_SVG =
  constant SUP_SVG (line 141) | const SUP_SVG =
  constant SUB_SVG (line 145) | const SUB_SVG =
  constant CHECK_BOX_SVG (line 149) | const CHECK_BOX_SVG =
  constant ENTER_SVG (line 153) | const ENTER_SVG =

FILE: packages/basic-modules/src/modules/blockquote/custom-types.ts
  type BlockQuoteElement (line 10) | type BlockQuoteElement = {

FILE: packages/basic-modules/src/modules/blockquote/elem-to-html.ts
  function quoteToHtml (line 8) | function quoteToHtml(elem: Element, childrenHtml: string): string {

FILE: packages/basic-modules/src/modules/blockquote/menu/BlockquoteMenu.ts
  class BlockquoteMenu (line 10) | class BlockquoteMenu implements IButtonMenu {
    method getValue (line 15) | getValue(editor: IDomEditor): string | boolean {
    method isActive (line 20) | isActive(editor: IDomEditor): boolean {
    method isDisabled (line 25) | isDisabled(editor: IDomEditor): boolean {
    method exec (line 55) | exec(editor: IDomEditor, value: string | boolean) {

FILE: packages/basic-modules/src/modules/blockquote/menu/index.ts
  method factory (line 10) | factory() {

FILE: packages/basic-modules/src/modules/blockquote/parse-elem-html.ts
  function parseHtml (line 11) | function parseHtml(

FILE: packages/basic-modules/src/modules/blockquote/plugin.ts
  function withBlockquote (line 9) | function withBlockquote<T extends IDomEditor>(editor: T): T {

FILE: packages/basic-modules/src/modules/blockquote/render-elem.tsx
  function renderBlockQuote (line 17) | function renderBlockQuote(

FILE: packages/basic-modules/src/modules/code-block/custom-types.ts
  type PureText (line 8) | type PureText = {
  type PreElement (line 12) | type PreElement = {
  type CodeElement (line 17) | type CodeElement = {

FILE: packages/basic-modules/src/modules/code-block/elem-to-html.ts
  function codeToHtml (line 8) | function codeToHtml(elem: Element, childrenHtml: string): string {
  function preToHtml (line 18) | function preToHtml(elem: Element, childrenHtml: string): string {

FILE: packages/basic-modules/src/modules/code-block/menu/CodeBlockMenu.ts
  class CodeBlockMenu (line 11) | class CodeBlockMenu implements IButtonMenu {
    method getSelectCodeElem (line 16) | private getSelectCodeElem(editor: IDomEditor): CodeElement | null {
    method getValue (line 30) | getValue(editor: IDomEditor): string | boolean {
    method isActive (line 36) | isActive(editor: IDomEditor): boolean {
    method isDisabled (line 41) | isDisabled(editor: IDomEditor): boolean {
    method exec (line 58) | exec(editor: IDomEditor, value: string | boolean) {
    method changeToPlainText (line 69) | private changeToPlainText(editor: IDomEditor) {
    method changeToCodeBlock (line 86) | private changeToCodeBlock(editor: IDomEditor, language: string) {

FILE: packages/basic-modules/src/modules/code-block/menu/index.ts
  method factory (line 10) | factory() {

FILE: packages/basic-modules/src/modules/code-block/parse-elem-html.ts
  function parseCodeHtml (line 11) | function parseCodeHtml(elem: DOMElement, children: Descendant[], editor:...
  function parsePreHtml (line 26) | function parsePreHtml(elem: DOMElement, children: Descendant[], editor: ...

FILE: packages/basic-modules/src/modules/code-block/plugin.ts
  function getLastTextLineBeforeSelection (line 9) | function getLastTextLineBeforeSelection(codeNode: SlateNode, editor: IDo...
  function withCodeBlock (line 23) | function withCodeBlock<T extends IDomEditor>(editor: T): T {

FILE: packages/basic-modules/src/modules/code-block/pre-parse-html.ts
  function preParse (line 13) | function preParse(codeElem: DOMElement): DOMElement {

FILE: packages/basic-modules/src/modules/code-block/render-elem.tsx
  function renderPre (line 10) | function renderPre(elemNode: SlateElement, children: VNode[] | null, edi...
  function renderCode (line 15) | function renderCode(elemNode: SlateElement, children: VNode[] | null, ed...

FILE: packages/basic-modules/src/modules/color/custom-types.ts
  type ColorText (line 8) | type ColorText = {

FILE: packages/basic-modules/src/modules/color/menu/BaseMenu.ts
  method exec (line 19) | exec(editor: IDomEditor, value: string | boolean) {
  method getValue (line 24) | getValue(editor: IDomEditor): string | boolean {
  method isActive (line 32) | isActive(editor: IDomEditor): boolean {
  method isDisabled (line 37) | isDisabled(editor: IDomEditor): boolean {
  method getPanelContentElem (line 57) | getPanelContentElem(editor: IDomEditor): DOMElement {

FILE: packages/basic-modules/src/modules/color/menu/BgColorMenu.ts
  class BgColorMenu (line 10) | class BgColorMenu extends BaseMenu {

FILE: packages/basic-modules/src/modules/color/menu/ColorMenu.ts
  class ColorMenu (line 10) | class ColorMenu extends BaseMenu {

FILE: packages/basic-modules/src/modules/color/menu/config.ts
  constant COLORS (line 6) | const COLORS = [
  function genColors (line 79) | function genColors() {
  function genBgColors (line 83) | function genBgColors() {

FILE: packages/basic-modules/src/modules/color/menu/index.ts
  method factory (line 12) | factory() {
  method factory (line 25) | factory() {

FILE: packages/basic-modules/src/modules/color/parse-style-html.ts
  function parseStyleHtml (line 11) | function parseStyleHtml(text: DOMElement, node: Descendant, editor: IDom...

FILE: packages/basic-modules/src/modules/color/pre-parse-html.ts
  function preParse (line 12) | function preParse(fontElem: DOMElement): DOMElement {

FILE: packages/basic-modules/src/modules/color/render-style.tsx
  function renderStyle (line 17) | function renderStyle(node: Descendant, vnode: VNode): VNode {

FILE: packages/basic-modules/src/modules/color/style-to-html.ts
  function styleToHtml (line 16) | function styleToHtml(textNode: Descendant, textHtml: string): string {

FILE: packages/basic-modules/src/modules/common/menu/EnterMenu.ts
  class EnterMenu (line 10) | class EnterMenu implements IButtonMenu {
    method getValue (line 15) | getValue(editor: IDomEditor): string | boolean {
    method isActive (line 19) | isActive(editor: IDomEditor): boolean {
    method isDisabled (line 23) | isDisabled(editor: IDomEditor): boolean {
    method exec (line 30) | exec(editor: IDomEditor, value: string | boolean) {

FILE: packages/basic-modules/src/modules/common/menu/index.ts
  method factory (line 10) | factory() {

FILE: packages/basic-modules/src/modules/divider/custom-types.ts
  type EmptyText (line 8) | type EmptyText = {
  type DividerElement (line 12) | type DividerElement = {

FILE: packages/basic-modules/src/modules/divider/elem-to-html.ts
  function dividerToHtml (line 8) | function dividerToHtml(elem: Element, childrenHtml: string): string {

FILE: packages/basic-modules/src/modules/divider/menu/InsertDividerMenu.ts
  class InsertDividerMenu (line 11) | class InsertDividerMenu implements IButtonMenu {
    method getValue (line 16) | getValue(editor: IDomEditor): string | boolean {
    method isActive (line 20) | isActive(editor: IDomEditor): boolean {
    method isDisabled (line 25) | isDisabled(editor: IDomEditor): boolean {
    method exec (line 41) | exec(editor: IDomEditor, value: string | boolean): void {

FILE: packages/basic-modules/src/modules/divider/menu/index.ts
  method factory (line 11) | factory() {

FILE: packages/basic-modules/src/modules/divider/parse-elem-html.ts
  function parseHtml (line 11) | function parseHtml(elem: DOMElement, children: Descendant[], editor: IDo...

FILE: packages/basic-modules/src/modules/divider/plugin.ts
  function withDivider (line 9) | function withDivider<T extends IDomEditor>(editor: T): T {

FILE: packages/basic-modules/src/modules/divider/render-elem.tsx
  function renderDivider (line 10) | function renderDivider(

FILE: packages/basic-modules/src/modules/emotion/menu/EmotionMenu.ts
  class EmotionMenu (line 11) | class EmotionMenu implements IDropPanelMenu {
    method exec (line 18) | exec(editor: IDomEditor, value: string | boolean) {
    method getValue (line 23) | getValue(editor: IDomEditor): string | boolean {
    method isActive (line 28) | isActive(editor: IDomEditor): boolean {
    method isDisabled (line 33) | isDisabled(editor: IDomEditor): boolean {
    method getPanelContentElem (line 52) | getPanelContentElem(editor: IDomEditor): DOMElement {

FILE: packages/basic-modules/src/modules/emotion/menu/config.ts
  function genConfig (line 6) | function genConfig() {

FILE: packages/basic-modules/src/modules/emotion/menu/index.ts
  method factory (line 11) | factory() {

FILE: packages/basic-modules/src/modules/font-size-family/custom-types.ts
  type FontSizeAndFamilyText (line 8) | type FontSizeAndFamilyText = {

FILE: packages/basic-modules/src/modules/font-size-family/menu/BaseMenu.ts
  method isActive (line 18) | isActive(editor: IDomEditor): boolean {
  method getValue (line 23) | getValue(editor: IDomEditor): string | boolean {
  method isDisabled (line 31) | isDisabled(editor: IDomEditor): boolean {
  method exec (line 51) | exec(editor: IDomEditor, value: string | boolean) {

FILE: packages/basic-modules/src/modules/font-size-family/menu/FontFamilyMenu.ts
  class FontFamilyMenu (line 10) | class FontFamilyMenu extends BaseMenu {
    method getOptions (line 16) | getOptions(editor: IDomEditor): IOption[] {

FILE: packages/basic-modules/src/modules/font-size-family/menu/FontSizeMenu.ts
  class FontSizeMenu (line 10) | class FontSizeMenu extends BaseMenu {
    method getOptions (line 15) | getOptions(editor: IDomEditor): IOption[] {

FILE: packages/basic-modules/src/modules/font-size-family/menu/config.ts
  function genFontSizeConfig (line 6) | function genFontSizeConfig() {
  function getFontFamilyConfig (line 26) | function getFontFamilyConfig() {

FILE: packages/basic-modules/src/modules/font-size-family/menu/index.ts
  method factory (line 12) | factory() {
  method factory (line 25) | factory() {

FILE: packages/basic-modules/src/modules/font-size-family/parse-style-html.ts
  function parseStyleHtml (line 11) | function parseStyleHtml(text: DOMElement, node: Descendant, editor: IDom...

FILE: packages/basic-modules/src/modules/font-size-family/pre-parse-html.ts
  constant FONT_SIZE_MAP_FOR_V4 (line 9) | const FONT_SIZE_MAP_FOR_V4 = {
  function preParse (line 23) | function preParse(fontElem: DOMElement): DOMElement {

FILE: packages/basic-modules/src/modules/font-size-family/render-style.tsx
  function renderStyle (line 17) | function renderStyle(node: Descendant, vnode: VNode): VNode {

FILE: packages/basic-modules/src/modules/font-size-family/style-to-html.ts
  function styleToHtml (line 16) | function styleToHtml(textNode: Descendant, textHtml: string): string {

FILE: packages/basic-modules/src/modules/full-screen/menu/FullScreen.ts
  class FullScreen (line 9) | class FullScreen implements IButtonMenu {
    method getValue (line 15) | getValue(editor: IDomEditor): string | boolean {
    method isActive (line 19) | isActive(editor: IDomEditor): boolean {
    method isDisabled (line 23) | isDisabled(editor: IDomEditor): boolean {
    method exec (line 27) | exec(editor: IDomEditor, value: string | boolean) {

FILE: packages/basic-modules/src/modules/full-screen/menu/index.ts
  method factory (line 10) | factory() {

FILE: packages/basic-modules/src/modules/header/custom-types.ts
  type Header1Element (line 10) | type Header1Element = {
  type Header2Element (line 15) | type Header2Element = {
  type Header3Element (line 20) | type Header3Element = {
  type Header4Element (line 25) | type Header4Element = {
  type Header5Element (line 30) | type Header5Element = {

FILE: packages/basic-modules/src/modules/header/elem-to-html.ts
  function genToHtmlFn (line 8) | function genToHtmlFn(level: number) {

FILE: packages/basic-modules/src/modules/header/helper.ts
  function getHeaderType (line 12) | function getHeaderType(editor: IDomEditor): string {
  function isMenuDisabled (line 30) | function isMenuDisabled(editor: IDomEditor): boolean {
  function setHeaderType (line 58) | function setHeaderType(editor: IDomEditor, type: string) {

FILE: packages/basic-modules/src/modules/header/menu/Header1ButtonMenu.ts
  class Header1ButtonMenu (line 8) | class Header1ButtonMenu extends HeaderButtonMenuBase {

FILE: packages/basic-modules/src/modules/header/menu/Header2ButtonMenu.ts
  class Header2ButtonMenu (line 8) | class Header2ButtonMenu extends HeaderButtonMenuBase {

FILE: packages/basic-modules/src/modules/header/menu/Header3ButtonMenu.ts
  class Header3ButtonMenu (line 8) | class Header3ButtonMenu extends HeaderButtonMenuBase {

FILE: packages/basic-modules/src/modules/header/menu/Header4ButtonMenu.ts
  class Header4ButtonMenu (line 8) | class Header4ButtonMenu extends HeaderButtonMenuBase {

FILE: packages/basic-modules/src/modules/header/menu/Header5ButtonMenu.ts
  class Header5ButtonMenu (line 8) | class Header5ButtonMenu extends HeaderButtonMenuBase {

FILE: packages/basic-modules/src/modules/header/menu/HeaderButtonMenuBase.ts
  method getValue (line 18) | getValue(editor: IDomEditor): string | boolean {
  method isActive (line 22) | isActive(editor: IDomEditor): boolean {
  method isDisabled (line 26) | isDisabled(editor: IDomEditor): boolean {
  method exec (line 30) | exec(editor: IDomEditor, value: string | boolean) {

FILE: packages/basic-modules/src/modules/header/menu/HeaderSelectMenu.ts
  class HeaderSelectMenu (line 10) | class HeaderSelectMenu implements ISelectMenu {
    method getOptions (line 16) | getOptions(editor: IDomEditor): IOption[] {
    method isActive (line 61) | isActive(editor: IDomEditor): boolean {
    method getValue (line 70) | getValue(editor: IDomEditor): string | boolean {
    method isDisabled (line 74) | isDisabled(editor: IDomEditor): boolean {
    method exec (line 83) | exec(editor: IDomEditor, value: string | boolean) {

FILE: packages/basic-modules/src/modules/header/menu/index.ts
  method factory (line 15) | factory() {
  method factory (line 22) | factory() {
  method factory (line 29) | factory() {
  method factory (line 36) | factory() {
  method factory (line 43) | factory() {
  method factory (line 50) | factory() {

FILE: packages/basic-modules/src/modules/header/parse-elem-html.ts
  function genParser (line 17) | function genParser<T>(level: number) {

FILE: packages/basic-modules/src/modules/header/plugin.ts
  function withHeader (line 9) | function withHeader<T extends IDomEditor>(editor: T): T {

FILE: packages/basic-modules/src/modules/header/render-elem.tsx
  function genRenderElem (line 10) | function genRenderElem(level: number) {

FILE: packages/basic-modules/src/modules/image/custom-types.ts
  type EmptyText (line 8) | type EmptyText = {
  type ImageStyle (line 12) | type ImageStyle = {
  type ImageElement (line 17) | type ImageElement = {

FILE: packages/basic-modules/src/modules/image/elem-to-html.ts
  function imageToHtml (line 9) | function imageToHtml(elemNode: Element, childrenHtml: string): string {

FILE: packages/basic-modules/src/modules/image/helper.ts
  function check (line 11) | async function check(
  function parseSrc (line 35) | async function parseSrc(menuKey: string, editor: IDomEditor, src: string...
  function insertImageNode (line 44) | async function insertImageNode(
  function updateImageNode (line 83) | async function updateImageNode(
  function isInsertImageMenuDisabled (line 123) | function isInsertImageMenuDisabled(editor: IDomEditor): boolean {

FILE: packages/basic-modules/src/modules/image/menu/DeleteImage.ts
  class DeleteImage (line 10) | class DeleteImage implements IButtonMenu {
    method getValue (line 15) | getValue(editor: IDomEditor): string | boolean {
    method isActive (line 20) | isActive(editor: IDomEditor): boolean {
    method isDisabled (line 25) | isDisabled(editor: IDomEditor): boolean {
    method exec (line 36) | exec(editor: IDomEditor, value: string | boolean) {

FILE: packages/basic-modules/src/modules/image/menu/EditImage.ts
  function genDomID (line 24) | function genDomID(): string {
  class EditImage (line 28) | class EditImage implements IModalMenu {
    method getValue (line 40) | getValue(editor: IDomEditor): string | boolean {
    method getImageNode (line 45) | private getImageNode(editor: IDomEditor): Node | null {
    method isActive (line 49) | isActive(editor: IDomEditor): boolean {
    method exec (line 54) | exec(editor: IDomEditor, value: string | boolean) {
    method isDisabled (line 59) | isDisabled(editor: IDomEditor): boolean {
    method getModalPositionNode (line 71) | getModalPositionNode(editor: IDomEditor): Node | null {
    method getModalContentElem (line 75) | getModalContentElem(editor: IDomEditor): DOMElement {
    method updateImage (line 134) | private updateImage(

FILE: packages/basic-modules/src/modules/image/menu/InsertImage.ts
  function genDomID (line 22) | function genDomID(): string {
  class InsertImage (line 26) | class InsertImage implements IModalMenu {
    method getValue (line 38) | getValue(editor: IDomEditor): string | boolean {
    method isActive (line 43) | isActive(editor: IDomEditor): boolean {
    method exec (line 48) | exec(editor: IDomEditor, value: string | boolean) {
    method isDisabled (line 53) | isDisabled(editor: IDomEditor): boolean {
    method getModalPositionNode (line 57) | getModalPositionNode(editor: IDomEditor): Node | null {
    method getModalContentElem (line 61) | getModalContentElem(editor: IDomEditor): DOMElement {
    method insertImage (line 113) | private insertImage(editor: IDomEditor, src: string, alt: string = '',...

FILE: packages/basic-modules/src/modules/image/menu/ViewImageLink.ts
  class ViewImageLink (line 10) | class ViewImageLink implements IButtonMenu {
    method getValue (line 15) | getValue(editor: IDomEditor): string | boolean {
    method isActive (line 24) | isActive(editor: IDomEditor): boolean {
    method isDisabled (line 29) | isDisabled(editor: IDomEditor): boolean {
    method exec (line 40) | exec(editor: IDomEditor, value: string | boolean) {

FILE: packages/basic-modules/src/modules/image/menu/Width100.ts
  class ImageWidth100 (line 8) | class ImageWidth100 extends ImageWidthBaseClass {

FILE: packages/basic-modules/src/modules/image/menu/Width30.ts
  class ImageWidth30 (line 8) | class ImageWidth30 extends ImageWidthBaseClass {

FILE: packages/basic-modules/src/modules/image/menu/Width50.ts
  class ImageWidth50 (line 8) | class ImageWidth50 extends ImageWidthBaseClass {

FILE: packages/basic-modules/src/modules/image/menu/WidthBase.ts
  method getValue (line 15) | getValue(editor: IDomEditor): string | boolean {
  method isActive (line 20) | isActive(editor: IDomEditor): boolean {
  method getSelectedNode (line 25) | private getSelectedNode(editor: IDomEditor): Node | null {
  method isDisabled (line 29) | isDisabled(editor: IDomEditor): boolean {
  method exec (line 40) | exec(editor: IDomEditor, value: string | boolean) {

FILE: packages/basic-modules/src/modules/image/menu/config.ts
  function genImageMenuConfig (line 8) | function genImageMenuConfig() {

FILE: packages/basic-modules/src/modules/image/menu/index.ts
  method factory (line 19) | factory() {
  method factory (line 30) | factory() {
  method factory (line 37) | factory() {
  method factory (line 45) | factory() {
  method factory (line 52) | factory() {
  method factory (line 59) | factory() {
  method factory (line 66) | factory() {

FILE: packages/basic-modules/src/modules/image/parse-elem-html.ts
  function parseHtml (line 11) | function parseHtml(elem: DOMElement, children: Descendant[], editor: IDo...

FILE: packages/basic-modules/src/modules/image/plugin.ts
  function withImage (line 9) | function withImage<T extends IDomEditor>(editor: T): T {

FILE: packages/basic-modules/src/modules/image/render-elem.tsx
  type IImageSize (line 13) | interface IImageSize {
  function genContainerId (line 18) | function genContainerId(editor: IDomEditor, elemNode: SlateElement) {
  function renderContainer (line 26) | function renderContainer(
  function renderResizeContainer (line 50) | function renderResizeContainer(
  function renderImage (line 175) | function renderImage(elemNode: SlateElement, children: VNode[] | null, e...

FILE: packages/basic-modules/src/modules/indent/custom-types.ts
  type IndentElement (line 10) | type IndentElement = {

FILE: packages/basic-modules/src/modules/indent/menu/BaseMenu.ts
  method getValue (line 18) | getValue(editor: IDomEditor): string | boolean {
  method isActive (line 31) | isActive(editor: IDomEditor): boolean {
  method getMatchNode (line 40) | protected getMatchNode(editor: IDomEditor): Node | null {

FILE: packages/basic-modules/src/modules/indent/menu/DecreaseIndentMenu.ts
  class DecreaseIndentMenu (line 12) | class DecreaseIndentMenu extends BaseMenu {
    method isDisabled (line 16) | isDisabled(editor: IDomEditor): boolean {
    method exec (line 29) | exec(editor: IDomEditor, value: string | boolean): void {

FILE: packages/basic-modules/src/modules/indent/menu/IncreaseIndentMenu.ts
  class IncreaseIndentMenu (line 13) | class IncreaseIndentMenu extends BaseMenu {
    method isDisabled (line 18) | isDisabled(editor: IDomEditor): boolean {
    method getIndentValue (line 31) | private getIndentValue(editor: IDomEditor) {
    method exec (line 49) | exec(editor: IDomEditor, value: string | boolean): void {

FILE: packages/basic-modules/src/modules/indent/menu/index.ts
  method factory (line 11) | factory() {
  method factory (line 18) | factory() {

FILE: packages/basic-modules/src/modules/indent/parse-style-html.ts
  function parseStyleHtml (line 11) | function parseStyleHtml(elem: DOMElement, node: Descendant, editor: IDom...

FILE: packages/basic-modules/src/modules/indent/pre-parse-html.ts
  function preParse (line 12) | function preParse(elem: DOMElement): DOMElement {

FILE: packages/basic-modules/src/modules/indent/render-style.tsx
  function renderStyle (line 17) | function renderStyle(node: Descendant, vnode: VNode): VNode {

FILE: packages/basic-modules/src/modules/indent/style-to-html.ts
  function styleToHtml (line 10) | function styleToHtml(node: Descendant, elemHtml: string): string {

FILE: packages/basic-modules/src/modules/justify/custom-types.ts
  type JustifyElement (line 10) | type JustifyElement = {

FILE: packages/basic-modules/src/modules/justify/menu/BaseMenu.ts
  method getValue (line 14) | getValue(editor: IDomEditor): string | boolean {
  method isActive (line 19) | isActive(editor: IDomEditor): boolean {
  method getMatchNode (line 28) | protected getMatchNode(editor: IDomEditor): Node | null {
  method isDisabled (line 48) | isDisabled(editor: IDomEditor): boolean {

FILE: packages/basic-modules/src/modules/justify/menu/JustifyCenterMenu.ts
  class JustifyCenterMenu (line 11) | class JustifyCenterMenu extends BaseMenu {
    method exec (line 15) | exec(editor: IDomEditor, value: string | boolean): void {

FILE: packages/basic-modules/src/modules/justify/menu/JustifyJustifyMenu.ts
  class JustifyJustifyMenu (line 11) | class JustifyJustifyMenu extends BaseMenu {
    method exec (line 15) | exec(editor: IDomEditor, value: string | boolean): void {

FILE: packages/basic-modules/src/modules/justify/menu/JustifyLeftMenu.ts
  class JustifyLeftMenu (line 11) | class JustifyLeftMenu extends BaseMenu {
    method exec (line 15) | exec(editor: IDomEditor, value: string | boolean): void {

FILE: packages/basic-modules/src/modules/justify/menu/JustifyRightMenu.ts
  class JustifyRightMenu (line 11) | class JustifyRightMenu extends BaseMenu {
    method exec (line 15) | exec(editor: IDomEditor, value: string | boolean): void {

FILE: packages/basic-modules/src/modules/justify/menu/index.ts
  method factory (line 13) | factory() {
  method factory (line 20) | factory() {
  method factory (line 27) | factory() {
  method factory (line 34) | factory() {

FILE: packages/basic-modules/src/modules/justify/parse-style-html.ts
  function parseStyleHtml (line 11) | function parseStyleHtml(elem: DOMElement, node: Descendant, editor: IDom...

FILE: packages/basic-modules/src/modules/justify/render-style.tsx
  function renderStyle (line 17) | function renderStyle(node: Descendant, vnode: VNode): VNode {

FILE: packages/basic-modules/src/modules/justify/style-to-html.ts
  function styleToHtml (line 10) | function styleToHtml(node: Descendant, elemHtml: string): string {

FILE: packages/basic-modules/src/modules/line-height/custom-types.ts
  type LineHeightElement (line 10) | type LineHeightElement = {

FILE: packages/basic-modules/src/modules/line-height/menu/LineHeightMenu.ts
  class LineHeightMenu (line 11) | class LineHeightMenu implements ISelectMenu {
    method getOptions (line 17) | getOptions(editor: IDomEditor): IOption[] {
    method getMatchNode (line 52) | private getMatchNode(editor: IDomEditor): Node | null {
    method isActive (line 73) | isActive(editor: IDomEditor): boolean {
    method getValue (line 82) | getValue(editor: IDomEditor): string | boolean {
    method isDisabled (line 90) | isDisabled(editor: IDomEditor): boolean {
    method exec (line 99) | exec(editor: IDomEditor, value: string | boolean) {

FILE: packages/basic-modules/src/modules/line-height/menu/config.ts
  function genLineHeightConfig (line 6) | function genLineHeightConfig() {

FILE: packages/basic-modules/src/modules/line-height/menu/index.ts
  method factory (line 11) | factory() {

FILE: packages/basic-modules/src/modules/line-height/parse-style-html.ts
  function parseStyleHtml (line 11) | function parseStyleHtml(elem: DOMElement, node: Descendant, editor: IDom...

FILE: packages/basic-modules/src/modules/line-height/render-style.tsx
  function renderStyle (line 17) | function renderStyle(node: Descendant, vnode: VNode): VNode {

FILE: packages/basic-modules/src/modules/line-height/style-to-html.ts
  function styleToHtml (line 10) | function styleToHtml(node: Descendant, elemHtml: string): string {

FILE: packages/basic-modules/src/modules/link/custom-types.ts
  type LinkElement (line 10) | type LinkElement = {

FILE: packages/basic-modules/src/modules/link/elem-to-html.ts
  function linkToHtml (line 9) | function linkToHtml(elem: Element, childrenHtml: string): string {

FILE: packages/basic-modules/src/modules/link/helper.ts
  function check (line 18) | async function check(
  function parse (line 48) | async function parse(menuKey: string, editor: IDomEditor, url: string): ...
  function isMenuDisabled (line 57) | function isMenuDisabled(editor: IDomEditor): boolean {
  function genLinkNode (line 75) | function genLinkNode(url: string, text?: string): LinkElement {
  function insertLink (line 90) | async function insertLink(editor: IDomEditor, text: string, url: string) {
  function updateLink (line 144) | async function updateLink(editor: IDomEditor, text: string, url: string) {

FILE: packages/basic-modules/src/modules/link/menu/EditLink.ts
  function genDomID (line 24) | function genDomID(): string {
  class EditLinkMenu (line 28) | class EditLinkMenu implements IModalMenu {
    method getSelectedLinkElem (line 39) | private getSelectedLinkElem(editor: IDomEditor): LinkElement | null {
    method getValue (line 49) | getValue(editor: IDomEditor): string | boolean {
    method isActive (line 57) | isActive(editor: IDomEditor): boolean {
    method exec (line 62) | exec(editor: IDomEditor, value: string | boolean) {
    method isDisabled (line 67) | isDisabled(editor: IDomEditor): boolean {
    method getModalPositionNode (line 78) | getModalPositionNode(editor: IDomEditor): Node | null {
    method getModalContentElem (line 82) | getModalContentElem(editor: IDomEditor): DOMElement {

FILE: packages/basic-modules/src/modules/link/menu/InsertLink.ts
  function genDomID (line 22) | function genDomID(): string {
  class InsertLinkMenu (line 26) | class InsertLinkMenu implements IModalMenu {
    method getValue (line 37) | getValue(editor: IDomEditor): string | boolean {
    method isActive (line 42) | isActive(editor: IDomEditor): boolean {
    method exec (line 47) | exec(editor: IDomEditor, value: string | boolean) {
    method isDisabled (line 52) | isDisabled(editor: IDomEditor): boolean {
    method getModalPositionNode (line 56) | getModalPositionNode(editor: IDomEditor): Node | null {
    method getModalContentElem (line 60) | getModalContentElem(editor: IDomEditor): DOMElement {

FILE: packages/basic-modules/src/modules/link/menu/UnLink.ts
  class UnLink (line 10) | class UnLink implements IButtonMenu {
    method getValue (line 15) | getValue(editor: IDomEditor): string | boolean {
    method isActive (line 20) | isActive(editor: IDomEditor): boolean {
    method isDisabled (line 25) | isDisabled(editor: IDomEditor): boolean {
    method exec (line 36) | exec(editor: IDomEditor, value: string | boolean) {

FILE: packages/basic-modules/src/modules/link/menu/ViewLink.ts
  class ViewLink (line 10) | class ViewLink implements IButtonMenu {
    method getSelectedLinkElem (line 15) | private getSelectedLinkElem(editor: IDomEditor): LinkElement | null {
    method getValue (line 21) | getValue(editor: IDomEditor): string | boolean {
    method isActive (line 29) | isActive(editor: IDomEditor): boolean {
    method isDisabled (line 34) | isDisabled(editor: IDomEditor): boolean {
    method exec (line 45) | exec(editor: IDomEditor, value: string | boolean) {

FILE: packages/basic-modules/src/modules/link/menu/config.ts
  function genLinkMenuConfig (line 6) | function genLinkMenuConfig() {

FILE: packages/basic-modules/src/modules/link/menu/index.ts
  method factory (line 16) | factory() {
  method factory (line 27) | factory() {
  method factory (line 35) | factory() {
  method factory (line 42) | factory() {

FILE: packages/basic-modules/src/modules/link/parse-elem-html.ts
  function parseHtml (line 11) | function parseHtml(elem: DOMElement, children: Descendant[], editor: IDo...

FILE: packages/basic-modules/src/modules/link/plugin.ts
  function withLink (line 11) | function withLink<T extends IDomEditor>(editor: T): T {

FILE: packages/basic-modules/src/modules/link/render-elem.tsx
  function renderLink (line 18) | function renderLink(elemNode: SlateElement, children: VNode[] | null, ed...

FILE: packages/basic-modules/src/modules/paragraph/custom-types.ts
  type ParagraphElement (line 10) | type ParagraphElement = {

FILE: packages/basic-modules/src/modules/paragraph/elem-to-html.ts
  function pToHtml (line 8) | function pToHtml(elem: Element, childrenHtml: string): string {

FILE: packages/basic-modules/src/modules/paragraph/parse-elem-html.ts
  function parseParagraphHtml (line 11) | function parseParagraphHtml(

FILE: packages/basic-modules/src/modules/paragraph/plugin.ts
  function deleteHandler (line 15) | function deleteHandler(newEditor: IDomEditor): boolean {
  function withParagraph (line 38) | function withParagraph<T extends IDomEditor>(editor: T): T {

FILE: packages/basic-modules/src/modules/paragraph/render-elem.tsx
  function renderParagraph (line 17) | function renderParagraph(

FILE: packages/basic-modules/src/modules/text-style/custom-types.ts
  type StyledText (line 8) | type StyledText = {

FILE: packages/basic-modules/src/modules/text-style/helper.ts
  function isMenuDisabled (line 9) | function isMenuDisabled(editor: IDomEditor, mark?: string): boolean {
  function removeMarks (line 29) | function removeMarks(editor: IDomEditor, textNode: Node) {

FILE: packages/basic-modules/src/modules/text-style/menu/BaseMenu.ts
  method getValue (line 22) | getValue(editor: IDomEditor): string | boolean {
  method isActive (line 38) | isActive(editor: IDomEditor): boolean {
  method isDisabled (line 43) | isDisabled(editor: IDomEditor): boolean {
  method exec (line 52) | exec(editor: IDomEditor, value: string | boolean) {

FILE: packages/basic-modules/src/modules/text-style/menu/BoldMenu.ts
  class BoldMenu (line 10) | class BoldMenu extends BaseMenu {

FILE: packages/basic-modules/src/modules/text-style/menu/ClearStyleMenu.ts
  class ClearStyleMenu (line 11) | class ClearStyleMenu implements IButtonMenu {
    method getValue (line 16) | getValue(editor: IDomEditor): string | boolean {
    method isActive (line 20) | isActive(editor: IDomEditor): boolean {
    method isDisabled (line 24) | isDisabled(editor: IDomEditor): boolean {
    method exec (line 33) | exec(editor: IDomEditor, value: string | boolean) {

FILE: packages/basic-modules/src/modules/text-style/menu/CodeMenu.ts
  class CodeMenu (line 10) | class CodeMenu extends BaseMenu {

FILE: packages/basic-modules/src/modules/text-style/menu/ItalicMenu.ts
  class ItalicMenu (line 10) | class ItalicMenu extends BaseMenu {

FILE: packages/basic-modules/src/modules/text-style/menu/SubMenu.ts
  class SubMenu (line 10) | class SubMenu extends BaseMenu {

FILE: packages/basic-modules/src/modules/text-style/menu/SupMenu.ts
  class SupMenu (line 10) | class SupMenu extends BaseMenu {

FILE: packages/basic-modules/src/modules/text-style/menu/ThroughMenu.ts
  class ThroughMenu (line 10) | class ThroughMenu extends BaseMenu {

FILE: packages/basic-modules/src/modules/text-style/menu/UnderlineMenu.ts
  class UnderlineMenu (line 10) | class UnderlineMenu extends BaseMenu {

FILE: packages/basic-modules/src/modules/text-style/menu/index.ts
  method factory (line 17) | factory() {
  method factory (line 24) | factory() {
  method factory (line 31) | factory() {
  method factory (line 38) | factory() {
  method factory (line 45) | factory() {
  method factory (line 52) | factory() {
  method factory (line 59) | factory() {
  method factory (line 66) | factory() {

FILE: packages/basic-modules/src/modules/text-style/parse-style-html.ts
  function isMatch (line 16) | function isMatch($text: Dom7Array, selector: string): boolean {
  function parseStyleHtml (line 26) | function parseStyleHtml(

FILE: packages/basic-modules/src/modules/text-style/render-style.tsx
  function renderStyle (line 16) | function renderStyle(node: Descendant, vnode: VNode): VNode {

FILE: packages/basic-modules/src/modules/text-style/style-to-html.ts
  function genStyledHtml (line 17) | function genStyledHtml(textNode: Descendant, html: string): string {
  function styleToHtml (line 36) | function styleToHtml(textNode: Descendant, textHtml: string): string {

FILE: packages/basic-modules/src/modules/todo/custom-types.ts
  type TodoElement (line 10) | type TodoElement = {

FILE: packages/basic-modules/src/modules/todo/elem-to-html.ts
  function todoToHtml (line 9) | function todoToHtml(elem: Element, childrenHtml: string): string {

FILE: packages/basic-modules/src/modules/todo/menu/Todo.ts
  class TodoMenu (line 10) | class TodoMenu implements IButtonMenu {
    method getValue (line 15) | getValue(editor: IDomEditor): string | boolean {
    method isActive (line 20) | isActive(editor: IDomEditor): boolean {
    method isDisabled (line 24) | isDisabled(editor: IDomEditor): boolean {
    method exec (line 39) | exec(editor: IDomEditor, value: string | boolean) {

FILE: packages/basic-modules/src/modules/todo/menu/index.ts
  method factory (line 10) | factory() {

FILE: packages/basic-modules/src/modules/todo/parse-elem-html.ts
  function parseHtml (line 11) | function parseHtml(elem: DOMElement, children: Descendant[], editor: IDo...

FILE: packages/basic-modules/src/modules/todo/plugin.ts
  function withTodo (line 9) | function withTodo<T extends IDomEditor>(editor: T): T {

FILE: packages/basic-modules/src/modules/todo/pre-parse-html.ts
  function preParse (line 12) | function preParse(elem: DOMElement): DOMElement {

FILE: packages/basic-modules/src/modules/todo/render-elem.tsx
  function renderTodo (line 18) | function renderTodo(elemNode: SlateElement, children: VNode[] | null, ed...

FILE: packages/basic-modules/src/modules/undo-redo/menu/RedoMenu.ts
  class RedoMenu (line 9) | class RedoMenu implements IButtonMenu {
    method getValue (line 14) | getValue(editor: IDomEditor): string | boolean {
    method isActive (line 18) | isActive(editor: IDomEditor): boolean {
    method isDisabled (line 22) | isDisabled(editor: IDomEditor): boolean {
    method exec (line 27) | exec(editor: IDomEditor, value: string | boolean) {

FILE: packages/basic-modules/src/modules/undo-redo/menu/UndoMenu.ts
  class UndoMenu (line 9) | class UndoMenu implements IButtonMenu {
    method getValue (line 14) | getValue(editor: IDomEditor): string | boolean {
    method isActive (line 18) | isActive(editor: IDomEditor): boolean {
    method isDisabled (line 22) | isDisabled(editor: IDomEditor): boolean {
    method exec (line 27) | exec(editor: IDomEditor, value: string | boolean) {

FILE: packages/basic-modules/src/modules/undo-redo/menu/index.ts
  method factory (line 11) | factory() {
  method factory (line 18) | factory() {

FILE: packages/basic-modules/src/utils/dom.ts
  function isPlainText (line 68) | function isPlainText(str: string) {
  function getOuterHTML (line 84) | function getOuterHTML($elem: Dom7Array) {
  function getTagName (line 93) | function getTagName($elem: Dom7Array): string {
  function getStyleValue (line 103) | function getStyleValue($elem: Dom7Array, styleKey: string): string {

FILE: packages/basic-modules/src/utils/util.ts
  function genRandomStr (line 13) | function genRandomStr(prefix: string = 'r'): string {
  function replaceSymbols (line 17) | function replaceSymbols(str: string) {

FILE: packages/basic-modules/src/utils/vdom.ts
  function addVnodeStyle (line 26) | function addVnodeStyle(vnode: VNode, newStyle: VNodeStyle) {

FILE: packages/code-highlight/src/constants/svg.ts
  constant JS_SVG (line 12) | const JS_SVG =

FILE: packages/code-highlight/src/custom-types.ts
  type PureText (line 8) | type PureText = {
  type PreElement (line 12) | type PreElement = {
  type CodeElement (line 17) | type CodeElement = {

FILE: packages/code-highlight/src/decorate/index.ts
  function getCodeElem (line 15) | function getCodeElem(textNode: Node): CodeElement | null {

FILE: packages/code-highlight/src/module/elem-to-html.ts
  function codeToHtml (line 9) | function codeToHtml(elem: Element, childrenHtml: string): string {

FILE: packages/code-highlight/src/module/menu/SelectLangMenu.ts
  class SelectLangMenu (line 11) | class SelectLangMenu implements ISelectMenu {
    method getOptions (line 18) | getOptions(editor: IDomEditor): IOption[] {
    method isActive (line 46) | isActive(editor: IDomEditor): boolean {
    method getValue (line 55) | getValue(editor: IDomEditor): string | boolean {
    method isDisabled (line 70) | isDisabled(editor: IDomEditor): boolean {
    method exec (line 77) | exec(editor: IDomEditor, value: string | boolean) {
    method getSelectCodeElem (line 88) | private getSelectCodeElem(editor: IDomEditor): CodeElement | null {

FILE: packages/code-highlight/src/module/menu/config.ts
  function genCodeLangs (line 6) | function genCodeLangs() {

FILE: packages/code-highlight/src/module/menu/index.ts
  method factory (line 11) | factory() {

FILE: packages/code-highlight/src/module/parse-style-html.ts
  function parseCodeStyleHtml (line 11) | function parseCodeStyleHtml(

FILE: packages/code-highlight/src/module/render-style.tsx
  function renderStyle (line 17) | function renderStyle(node: Descendant, vnode: VNode): VNode {

FILE: packages/code-highlight/src/utils/vdom.ts
  function addVnodeClassName (line 13) | function addVnodeClassName(vnode: VNode, className: string) {
  function addVnodeStyle (line 26) | function addVnodeStyle(vnode: VNode, newStyle: VNodeStyle) {

FILE: packages/code-highlight/src/vendor/prism.ts
  function getPrismTokenLength (line 71) | function getPrismTokenLength(token: any) {
  function getPrismTokens (line 91) | function getPrismTokens(textNode: Text, language: string) {

FILE: packages/core/__tests__/config/editor-config.test.ts
  function getStartLocation (line 10) | function getStartLocation(editor) {

FILE: packages/core/__tests__/config/toolbar-config.test.ts
  function createToolbar (line 14) | function createToolbar(editor: IDomEditor, customConfig = {}) {

FILE: packages/core/__tests__/editor/dom-editor.test.ts
  function genStartLocation (line 16) | function genStartLocation() {

FILE: packages/core/__tests__/editor/plugins/with-config.test.ts
  function createEditor (line 9) | function createEditor(...args) {

FILE: packages/core/__tests__/editor/plugins/with-content.test.ts
  function createEditor (line 11) | function createEditor(...args) {
  function setEditorSelection (line 17) | function setEditorSelection(
  function getStartLocation (line 41) | function getStartLocation(editor) {

FILE: packages/core/__tests__/editor/plugins/with-dom.test.ts
  function createEditor (line 10) | function createEditor(...args) {
  function getStartLocation (line 15) | function getStartLocation(editor) {

FILE: packages/core/__tests__/editor/plugins/with-emitter.test.ts
  function createEditor (line 9) | function createEditor(...args) {

FILE: packages/core/__tests__/editor/plugins/with-selection.test.ts
  function createEditor (line 10) | function createEditor(...args) {
  function getStartLocation (line 15) | function getStartLocation(editor) {
  function genParagraph (line 18) | function genParagraph() {

FILE: packages/core/__tests__/menus/register-menus/register-button-menu.ts
  class MyButtonMenu (line 9) | class MyButtonMenu implements IButtonMenu {
    method getValue (line 12) | getValue(editor: IDomEditor) {
    method isActive (line 15) | isActive(editor: IDomEditor) {
    method isDisabled (line 18) | isDisabled(editor: IDomEditor) {
    method exec (line 21) | exec(editor: IDomEditor, value: string | boolean) {
  method factory (line 28) | factory() {

FILE: packages/core/__tests__/menus/register-menus/register-modal-menu.ts
  class MyModalMenu (line 9) | class MyModalMenu implements IModalMenu {
    method getValue (line 14) | getValue(editor: IDomEditor) {
    method isActive (line 17) | isActive(editor: IDomEditor) {
    method isDisabled (line 20) | isDisabled(editor: IDomEditor) {
    method exec (line 23) | exec(editor: IDomEditor, value: string | boolean) {
    method getModalContentElem (line 26) | getModalContentElem(editor: IDomEditor) {
    method getModalPositionNode (line 29) | getModalPositionNode(editor: IDomEditor) {
  method factory (line 36) | factory() {

FILE: packages/core/__tests__/menus/register-menus/register-select-menu.ts
  class MySelectMenu (line 9) | class MySelectMenu implements ISelectMenu {
    method getValue (line 12) | getValue(editor: IDomEditor) {
    method isActive (line 15) | isActive(editor: IDomEditor) {
    method isDisabled (line 18) | isDisabled(editor: IDomEditor) {
    method exec (line 21) | exec(editor: IDomEditor, value: string | boolean) {
    method getOptions (line 24) | getOptions(): IOption[] {
  method factory (line 34) | factory() {

FILE: packages/core/src/config/index.ts
  function genEditorConfig (line 14) | function genEditorConfig(userConfig: Partial<IEditorConfig> = {}): IEdit...
  function genToolbarConfig (line 52) | function genToolbarConfig(userConfig?: Partial<IToolbarConfig>): IToolba...

FILE: packages/core/src/config/interface.ts
  type IHoverbarConf (line 10) | interface IHoverbarConf {
  type AlertType (line 18) | type AlertType = 'success' | 'info' | 'warning' | 'error'
  type ISingleMenuConfig (line 20) | interface ISingleMenuConfig {
  type IMenuConfig (line 24) | interface IMenuConfig {
  type IEditorConfig (line 31) | interface IEditorConfig {
  type IToolbarConfig (line 69) | interface IToolbarConfig {

FILE: packages/core/src/config/register.ts
  constant GLOBAL_MENU_CONF (line 9) | const GLOBAL_MENU_CONF: IMenuConfig = {}
  function registerGlobalMenuConf (line 16) | function registerGlobalMenuConf(key: string, config?: ISingleMenuConfig) {

FILE: packages/core/src/constants/index.ts
  constant IGNORE_TAGS (line 1) | const IGNORE_TAGS = new Set([

FILE: packages/core/src/constants/svg.ts
  constant SVG_CHECK_MARK (line 13) | const SVG_CHECK_MARK =
  constant SVG_DOWN_ARROW (line 17) | const SVG_DOWN_ARROW =
  constant SVG_CLOSE (line 21) | const SVG_CLOSE =

FILE: packages/core/src/create/bind-node-relation.ts
  function bindNodeRelation (line 17) | function bindNodeRelation(node: Node, index: number, parent: Ancestor, e...

FILE: packages/core/src/create/create-editor.ts
  type PluginFnType (line 34) | type PluginFnType = <T extends IDomEditor>(editor: T) => T
  type ICreateOption (line 36) | interface ICreateOption {

FILE: packages/core/src/create/create-toolbar.ts
  type ICreateOption (line 14) | interface ICreateOption {

FILE: packages/core/src/create/helper.ts
  function isRepeatedCreate (line 11) | function isRepeatedCreate(
  function isRepeatedCreateTextarea (line 36) | function isRepeatedCreateTextarea(
  function isRepeatedCreateToolbar (line 46) | function isRepeatedCreateToolbar(
  function genDefaultContent (line 56) | function genDefaultContent() {
  function htmlToContent (line 70) | function htmlToContent(editor: IDomEditor, html: string = ''): Descendan...

FILE: packages/core/src/editor/dom-editor.ts
  method getWindow (line 47) | getWindow(editor: IDomEditor): Window {
  method findKey (line 59) | findKey(editor: IDomEditor | null, node: Node): Key {
  method setNewKey (line 71) | setNewKey(node: Node) {
  method findPath (line 80) | findPath(editor: IDomEditor | null, node: Node): Path {
  method findDocumentOrShadowRoot (line 117) | findDocumentOrShadowRoot(editor: IDomEditor): Document | ShadowRoot {
  method getParentNode (line 136) | getParentNode(editor: IDomEditor | null, node: Node): Ancestor | null {
  method getParentsNodes (line 145) | getParentsNodes(editor: IDomEditor, node: Node): Ancestor[] {
  method getTopNode (line 165) | getTopNode(editor: IDomEditor, curNode: Node): Node {
  method toDOMNode (line 174) | toDOMNode(editor: IDomEditor, node: Node): HTMLElement {
  method hasDOMNode (line 194) | hasDOMNode(editor: IDomEditor, target: DOMNode, options: { editable?: bo...
  method toDOMRange (line 231) | toDOMRange(editor: IDomEditor, range: Range): DOMRange {
  method toDOMPoint (line 258) | toDOMPoint(editor: IDomEditor, point: Point): DOMPoint {
  method toSlateNode (line 308) | toSlateNode(editor: IDomEditor | null, domNode: DOMNode): Node {
  method findEventRange (line 327) | findEventRange(editor: IDomEditor, event: any): Range {
  method toSlateRange (line 393) | toSlateRange<T extends boolean>(
  method toSlatePoint (line 476) | toSlatePoint<T extends boolean>(
  method hasRange (line 571) | hasRange(editor: IDomEditor, range: Range): boolean {
  method getNodeType (line 576) | getNodeType(node: Node): string {
  method checkNodeType (line 583) | checkNodeType(node: Node, type: string) {
  method getNodesStr (line 587) | getNodesStr(nodes: Node[]): string {
  method getSelectedElems (line 591) | getSelectedElems(editor: IDomEditor): Element[] {
  method getSelectedNodeByType (line 603) | getSelectedNodeByType(editor: IDomEditor, type: string): Node | null {
  method getSelectedTextNode (line 613) | getSelectedTextNode(editor: IDomEditor): Node | null {
  method isNodeSelected (line 623) | isNodeSelected(editor: IDomEditor, node: Node): boolean {
  method isSelectionAtLineEnd (line 636) | isSelectionAtLineEnd(editor: IDomEditor, path: Path): boolean {
  method getTextarea (line 648) | getTextarea(editor: IDomEditor): TextArea {
  method getToolbar (line 655) | getToolbar(editor: IDomEditor): Toolbar | null {
  method getHoverbar (line 660) | getHoverbar(editor: IDomEditor): HoverBar | null {
  method normalizeContent (line 665) | normalizeContent(editor: IDomEditor) {
  method getLeftLengthOfMaxLength (line 675) | getLeftLengthOfMaxLength(editor: IDomEditor): number {
  method cleanExposedTexNodeInSelectionBlock (line 694) | cleanExposedTexNodeInSelectionBlock(editor: IDomEditor) {
  method isLastNode (line 750) | isLastNode(editor: IDomEditor, node: Node) {
  method genEmptyParagraph (line 759) | genEmptyParagraph(): Element {
  method isSelectedVoidNode (line 767) | isSelectedVoidNode(editor: IDomEditor): boolean {
  method isSelectedEmptyParagraph (line 782) | isSelectedEmptyParagraph(editor: IDomEditor) {
  method isEmptyPath (line 803) | isEmptyPath(editor: IDomEditor, path: Path): boolean {

FILE: packages/core/src/editor/interface.ts
  type ElementWithId (line 12) | type ElementWithId = Element & { id: string }
  type IDomEditor (line 17) | interface IDomEditor extends Editor {

FILE: packages/core/src/editor/plugins/with-content.ts
  function insertElemToEditor (line 26) | function insertElemToEditor(editor: IDomEditor, elem: Element) {

FILE: packages/core/src/editor/plugins/with-emitter.ts
  function getEmitter (line 15) | function getEmitter(editor: IDomEditor): Emitter {
  constant EDITOR_TO_DESTROY_LISTENERS (line 25) | const EDITOR_TO_DESTROY_LISTENERS: WeakMap<IDomEditor, Set<Function>> = ...
  function recordDestroyListeners (line 26) | function recordDestroyListeners(editor: IDomEditor, fn: Function) {
  function getDestroyListeners (line 34) | function getDestroyListeners(editor: IDomEditor): Set<Function> {
  function clearDestroyListeners (line 37) | function clearDestroyListeners(editor: IDomEditor) {

FILE: packages/core/src/i18n/index.ts
  function i18nAddResources (line 22) | function i18nAddResources(lng: string, resources: object) {
  function i18nChangeLanguage (line 30) | function i18nChangeLanguage(lng: string) {
  function i18nGetResources (line 38) | function i18nGetResources(lng: string) {

FILE: packages/core/src/index.ts
  type IModuleConf (line 42) | interface IModuleConf {

FILE: packages/core/src/menus/bar-item/BaseButton.ts
  method constructor (line 19) | constructor(key: string, menu: IButtonMenu | IDropPanelMenu | IModalMenu...
  method init (line 53) | private init() {
  method exec (line 75) | private exec() {
  method setActive (line 85) | private setActive() {
  method setDisabled (line 100) | private setDisabled() {
  method changeMenuState (line 125) | changeMenuState() {

FILE: packages/core/src/menus/bar-item/DropPanelButton.ts
  class DropPanelButton (line 12) | class DropPanelButton extends BaseButton {
    method constructor (line 16) | constructor(key: string, menu: IDropPanelMenu, inGroup = false) {
    method onButtonClick (line 27) | onButtonClick() {
    method handleDropPanel (line 34) | private handleDropPanel() {

FILE: packages/core/src/menus/bar-item/GroupButton.ts
  class GroupButton (line 11) | class GroupButton {
    method constructor (line 16) | constructor(menu: IMenuGroup) {
    method appendBarItem (line 44) | appendBarItem(barItem: IBarItem) {
    method observe (line 49) | private observe(observer: MutationObserver) {
    method createObserver (line 54) | private createObserver(): MutationObserver {

FILE: packages/core/src/menus/bar-item/ModalButton.ts
  class ModalButton (line 15) | class ModalButton extends BaseButton {
    method constructor (line 20) | constructor(key: string, menu: IModalMenu, inGroup = false) {
    method onButtonClick (line 25) | onButtonClick() {
    method getPosition (line 34) | private getPosition(): Partial<IPositionStyle> {
    method handleModal (line 48) | private handleModal() {
    method renderAndShowModal (line 77) | private renderAndShowModal(modal: Modal, firstTime: boolean = false) {

FILE: packages/core/src/menus/bar-item/Select.ts
  function getOptionText (line 15) | function getOptionText(options: IOption[], value: string): string {
  class BarItemSelect (line 28) | class BarItemSelect implements IBarItem {
    method constructor (line 35) | constructor(key: string, menu: ISelectMenu, inGroup = false) {
    method init (line 55) | private init() {
    method trigger (line 68) | private trigger() {
    method onChange (line 111) | private onChange(value: string) {
    method setSelectedValue (line 117) | private setSelectedValue() {
    method setDisabled (line 132) | private setDisabled() {
    method changeMenuState (line 155) | changeMenuState() {

FILE: packages/core/src/menus/bar-item/SimpleButton.ts
  class SimpleButton (line 9) | class SimpleButton extends BaseButton {
    method constructor (line 10) | constructor(key: string, menu: IButtonMenu, inGroup = false) {
    method onButtonClick (line 13) | onButtonClick() {

FILE: packages/core/src/menus/bar-item/index.ts
  type MenuType (line 16) | type MenuType = IButtonMenu | ISelectMenu | IDropPanelMenu | IModalMenu
  type IBarItem (line 18) | interface IBarItem {
  constant MENU_TO_BAR_ITEM (line 25) | const MENU_TO_BAR_ITEM = new WeakMap<MenuType, IBarItem>()
  function getEditorInstance (line 27) | function getEditorInstance(item: IBarItem): IDomEditor {
  function createBarItem (line 39) | function createBarItem(key: string, menu: MenuType, inGroup: boolean = f...
  function createBarItemGroup (line 69) | function createBarItemGroup(menu: IMenuGroup): GroupButton {

FILE: packages/core/src/menus/bar-item/tooltip.ts
  function addTooltip (line 9) | function addTooltip(

FILE: packages/core/src/menus/bar/HoverBar.ts
  type MenuType (line 20) | type MenuType = IButtonMenu | ISelectMenu | IDropPanelMenu | IModalMenu
  function isSelectedText (line 27) | function isSelectedText(editor: IDomEditor, n: Node) {
  class HoverBar (line 45) | class HoverBar {
    method constructor (line 52) | constructor() {
    method getMenus (line 77) | getMenus() {
    method hideAndClean (line 81) | hideAndClean() {
    method checkPositionBottom (line 96) | private checkPositionBottom() {
    method show (line 116) | private show() {
    method changeItemsState (line 124) | private changeItemsState() {
    method registerItems (line 132) | private registerItems(menuKeys: string[]) {
    method registerSingleItem (line 149) | private registerSingleItem(key: string) {
    method setPosition (line 182) | private setPosition(node: Node) {
    method getSelectedNodeAndMenuKeys (line 208) | private getSelectedNodeAndMenuKeys(): { node: Node; menuKeys: string[]...
    method getEditorInstance (line 291) | private getEditorInstance(): IDomEditor {
    method getHoverbarKeysConf (line 297) | private getHoverbarKeysConf() {
    method isSamePath (line 313) | private isSamePath(node1: Node | null, node2: Node | null) {
    method destroy (line 327) | destroy() {

FILE: packages/core/src/menus/bar/Toolbar.ts
  type MenuType (line 19) | type MenuType = IButtonMenu | ISelectMenu | IDropPanelMenu | IModalMenu
  class Toolbar (line 21) | class Toolbar {
    method constructor (line 28) | constructor(boxSelector: string | DOMElement, config: Partial<IToolbar...
    method getMenus (line 56) | getMenus() {
    method getConfig (line 60) | getConfig() {
    method registerItems (line 65) | private registerItems() {
    method registerGroup (line 128) | private registerGroup(menu: IMenuGroup) {
    method registerSingleItem (line 148) | private registerSingleItem(key: string, container: GroupButton | Toolb...
    method getEditorInstance (line 191) | private getEditorInstance(): IDomEditor {
    method destroy (line 209) | destroy() {

FILE: packages/core/src/menus/helpers/helpers.ts
  function clearSvgStyle (line 13) | function clearSvgStyle($elem: Dom7Array) {
  function gen$downArrow (line 30) | function gen$downArrow() {
  function gen$barItemDivider (line 38) | function gen$barItemDivider() {

FILE: packages/core/src/menus/helpers/position.ts
  function getTextContainerRect (line 18) | function getTextContainerRect(editor: IDomEditor): {
  function getPositionBySelection (line 39) | function getPositionBySelection(editor: IDomEditor): Partial<IPositionSt...
  function getPositionByNode (line 100) | function getPositionByNode(
  function correctPosition (line 216) | function correctPosition(editor: IDomEditor, $positionElem: Dom7Array) {

FILE: packages/core/src/menus/interface.ts
  type IMenuGroup (line 10) | interface IMenuGroup {
  type IPositionStyle (line 17) | interface IPositionStyle {
  type IOption (line 24) | interface IOption {
  type IBaseMenu (line 31) | interface IBaseMenu {
  type IButtonMenu (line 47) | interface IButtonMenu extends IBaseMenu {
  type ISelectMenu (line 51) | interface ISelectMenu extends IBaseMenu {
  type IDropPanelMenu (line 56) | interface IDropPanelMenu extends IBaseMenu {
  type IModalMenu (line 61) | interface IModalMenu extends IBaseMenu {
  type MenuFactoryType (line 68) | type MenuFactoryType = () => IButtonMenu | ISelectMenu | IDropPanelMenu ...
  type IRegisterMenuConf (line 70) | interface IRegisterMenuConf {

FILE: packages/core/src/menus/panel-and-modal/BaseClass.ts
  method constructor (line 16) | constructor(editor: IDomEditor) {
  method record (line 23) | private record(editor: IDomEditor) {
  method renderContent (line 39) | renderContent(contentElem: DOMElement) {
  method appendTo (line 51) | appendTo($menuElem: Dom7Array) {
  method show (line 56) | show() {
  method hide (line 69) | hide() {

FILE: packages/core/src/menus/panel-and-modal/DropPanel.ts
  class DropPanel (line 10) | class DropPanel extends PanelAndModal {
    method constructor (line 14) | constructor(editor: IDomEditor) {
    method genSelfElem (line 18) | genSelfElem(): Dom7Array | null {

FILE: packages/core/src/menus/panel-and-modal/Modal.ts
  class Modal (line 14) | class Modal extends PanelAndModal {
    method constructor (line 19) | constructor(editor: IDomEditor, width: number = 0) {
    method genSelfElem (line 42) | genSelfElem(): Dom7Array | null {
    method setStyle (line 54) | setStyle(positionStyle: Partial<IPositionStyle>) {
  function genModalInputElems (line 75) | function genModalInputElems(
  function genModalTextareaElems (line 95) | function genModalTextareaElems(
  function genModalButtonElems (line 116) | function genModalButtonElems(buttonId: string, buttonText: string): DOME...

FILE: packages/core/src/menus/panel-and-modal/SelectList.ts
  function gen$SelectedIcon (line 13) | function gen$SelectedIcon() {
  class SelectList (line 17) | class SelectList extends PanelAndModal {
    method constructor (line 21) | constructor(editor: IDomEditor, width?: number) {
    method renderList (line 39) | renderList(options: IOption[]) {
    method genSelfElem (line 65) | genSelfElem(): Dom7Array | null {

FILE: packages/core/src/menus/register.ts
  constant MENU_ITEM_FACTORIES (line 10) | const MENU_ITEM_FACTORIES: {
  function registerMenu (line 19) | function registerMenu(

FILE: packages/core/src/parse-html/helper.ts
  constant REPLACE_SPACE_160_REG (line 6) | const REPLACE_SPACE_160_REG = new RegExp(String.fromCharCode(160), 'g')
  function replaceSpace160 (line 13) | function replaceSpace160(str: string): string {

FILE: packages/core/src/parse-html/index.ts
  constant TEXT_TAGS (line 11) | const TEXT_TAGS = [
  type PreParseHtmlFnType (line 26) | type PreParseHtmlFnType = ($node: DOMElement) => DOMElement
  type IPreParseHtmlConf (line 28) | interface IPreParseHtmlConf {
  constant PRE_PARSE_HTML_CONF_LIST (line 33) | const PRE_PARSE_HTML_CONF_LIST: IPreParseHtmlConf[] = []
  function registerPreParseHtmlConf (line 39) | function registerPreParseHtmlConf(conf: IPreParseHtmlConf) {
  type ParseStyleHtmlFnType (line 45) | type ParseStyleHtmlFnType = (
  constant PARSE_STYLE_HTML_FN_LIST (line 51) | const PARSE_STYLE_HTML_FN_LIST: ParseStyleHtmlFnType[] = []
  function registerParseStyleHtmlHandler (line 57) | function registerParseStyleHtmlHandler(fn: ParseStyleHtmlFnType) {
  type ParseElemHtmlFnType (line 63) | type ParseElemHtmlFnType = (
  constant PARSE_ELEM_HTML_CONF (line 69) | const PARSE_ELEM_HTML_CONF: {
  type IParseElemHtmlConf (line 73) | interface IParseElemHtmlConf {
  function registerParseElemHtmlConf (line 78) | function registerParseElemHtmlConf(conf: IParseElemHtmlConf) {

FILE: packages/core/src/parse-html/parse-common-elem-html.ts
  function tryInsertTextToChildrenLastItem (line 20) | function tryInsertTextToChildrenLastItem(children: Descendant[], str: st...
  function genChildren (line 41) | function genChildren($elem: Dom7Array, editor: IDomEditor): Descendant[] {
  function defaultParser (line 114) | function defaultParser(elem: DOMElement, children: Descendant[], editor:...
  function getParser (line 125) | function getParser($elem: Dom7Array): ParseElemHtmlFnType {
  function parseCommonElemHtml (line 140) | function parseCommonElemHtml($elem: Dom7Array, editor: IDomEditor): Elem...

FILE: packages/core/src/parse-html/parse-elem-html.ts
  function parseElemHtml (line 20) | function parseElemHtml($elem: Dom7Array, editor: IDomEditor): Descendant...

FILE: packages/core/src/parse-html/parse-text-elem-html.ts
  function parseTextElemHtml (line 19) | function parseTextElemHtml($text: Dom7Array, editor: IDomEditor): Text {

FILE: packages/core/src/render/element/getRenderElem.tsx
  function defaultRender (line 18) | function defaultRender(
  function getRenderElem (line 34) | function getRenderElem(type: string): RenderElemFnType {

FILE: packages/core/src/render/element/renderElement.tsx
  type IAttrs (line 24) | interface IAttrs {
  function renderElement (line 33) | function renderElement(elemNode: SlateElement, editor: IDomEditor): VNode {

FILE: packages/core/src/render/element/renderStyle.ts
  function renderStyle (line 15) | function renderStyle(elem: SlateElement, vnode: VNode): VNode {

FILE: packages/core/src/render/helper.ts
  function genElemId (line 6) | function genElemId(id: string) {
  function genTextId (line 10) | function genTextId(id: string) {

FILE: packages/core/src/render/index.ts
  type RenderStyleFnType (line 12) | type RenderStyleFnType = (node: Descendant, vnode: VNode) => VNode
  constant RENDER_STYLE_HANDLER_LIST (line 15) | const RENDER_STYLE_HANDLER_LIST: RenderStyleFnType[] = []
  function registerStyleHandler (line 21) | function registerStyleHandler(fn: RenderStyleFnType) {
  type RenderElemFnType (line 27) | type RenderElemFnType = (
  constant RENDER_ELEM_CONF (line 34) | const RENDER_ELEM_CONF: {
  type IRenderElemConf (line 38) | interface IRenderElemConf {
  function registerRenderElemConf (line 47) | function registerRenderElemConf(conf: IRenderElemConf) {

FILE: packages/core/src/render/node2Vnode.ts
  function node2Vnode (line 20) | function node2Vnode(node: Node, index: number, parent: Ancestor, editor:...

FILE: packages/core/src/render/text/genVnode.tsx
  function str (line 11) | function str(text: string, isTrailing = false): VNode {
  function zeroWidthStr (line 15) | function zeroWidthStr(length = 0, isLineBreak = false): VNode {
  function genTextVnode (line 24) | function genTextVnode(

FILE: packages/core/src/render/text/renderStyle.ts
  function addTextVnodeStyle (line 15) | function addTextVnodeStyle(leafNode: SlateText, textVnode: VNode): VNode {

FILE: packages/core/src/render/text/renderText.tsx
  function renderText (line 17) | function renderText(textNode: SlateText, parent: Ancestor, editor: IDomE...

FILE: packages/core/src/text-area/TextArea.ts
  class TextArea (line 21) | class TextArea {
    method constructor (line 37) | constructor(boxSelector: string | DOMElement) {
    method editorInstance (line 88) | private get editorInstance(): IDomEditor {
    method bindEvent (line 102) | private bindEvent() {
    method onFocusAndOnBlur (line 129) | private onFocusAndOnBlur() {
    method changeMaxLengthInfo (line 150) | private changeMaxLengthInfo() {
    method changeProgress (line 164) | changeProgress(progress: number) {
    method changeViewState (line 181) | changeViewState() {
    method destroy (line 200) | destroy() {

FILE: packages/core/src/text-area/event-handlers/beforeInput.ts
  type BeforeInputEventType (line 16) | interface BeforeInputEventType {
  function handleBeforeInput (line 24) | function handleBeforeInput(e: Event, textarea: TextArea, editor: IDomEdi...

FILE: packages/core/src/text-area/event-handlers/blur.ts
  function handleOnBlur (line 15) | function handleOnBlur(e: Event, textarea: TextArea, editor: IDomEditor) {

FILE: packages/core/src/text-area/event-handlers/click.ts
  function handleOnClick (line 13) | function handleOnClick(event: Event, textarea: TextArea, editor: IDomEdi...

FILE: packages/core/src/text-area/event-handlers/composition.ts
  constant EDITOR_TO_TEXT (line 16) | const EDITOR_TO_TEXT: WeakMap<IDomEditor, string> = new WeakMap()
  constant EDITOR_TO_START_CONTAINER (line 17) | const EDITOR_TO_START_CONTAINER: WeakMap<IDomEditor, DOMNode> = new Weak...
  function handleCompositionStart (line 25) | function handleCompositionStart(e: Event, textarea: TextArea, editor: ID...
  function handleCompositionUpdate (line 65) | function handleCompositionUpdate(event: Event, textarea: TextArea, edito...
  function handleCompositionEnd (line 77) | function handleCompositionEnd(e: Event, textarea: TextArea, editor: IDom...

FILE: packages/core/src/text-area/event-handlers/copy.ts
  function handleOnCopy (line 11) | function handleOnCopy(e: Event, textarea: TextArea, editor: IDomEditor) {

FILE: packages/core/src/text-area/event-handlers/cut.ts
  function handleOnCut (line 11) | function handleOnCut(e: Event, textarea: TextArea, editor: IDomEditor) {

FILE: packages/core/src/text-area/event-handlers/drag.ts
  function handleOnDragstart (line 12) | function handleOnDragstart(e: Event, textarea: TextArea, editor: IDomEdi...
  function handleOnDragover (line 38) | function handleOnDragover(event: Event, textarea: TextArea, editor: IDom...
  function handleOnDragend (line 50) | function handleOnDragend(e: Event, textarea: TextArea, editor: IDomEdito...

FILE: packages/core/src/text-area/event-handlers/drop.ts
  function handleOnDrop (line 13) | function handleOnDrop(e: Event, textarea: TextArea, editor: IDomEditor) {

FILE: packages/core/src/text-area/event-handlers/focus.ts
  function handleOnFocus (line 12) | function handleOnFocus(event: Event, textarea: TextArea, editor: IDomEdi...

FILE: packages/core/src/text-area/event-handlers/keydown.ts
  function preventDefault (line 15) | function preventDefault(event: Event) {
  function triggerMenuHotKey (line 20) | function triggerMenuHotKey(editor: IDomEditor, event: KeyboardEvent) {
  function handleOnKeydown (line 41) | function handleOnKeydown(e: Event, textarea: TextArea, editor: IDomEdito...

FILE: packages/core/src/text-area/event-handlers/keypress.ts
  function handleKeypress (line 14) | function handleKeypress(event: Event, textarea: TextArea, editor: IDomEd...

FILE: packages/core/src/text-area/event-handlers/paste.ts
  function handleOnPaste (line 14) | function handleOnPaste(e: Event, textarea: TextArea, editor: IDomEditor) {

FILE: packages/core/src/text-area/helpers.ts
  function hasEditableTarget (line 30) | function hasEditableTarget(
  function isTargetInsideNonReadonlyVoid (line 40) | function isTargetInsideNonReadonlyVoid(
  function hasTarget (line 54) | function hasTarget(editor: IDomEditor, target: EventTarget | null): targ...
  function isDOMEventHandled (line 61) | function isDOMEventHandled(event: Event, handler?: (event: Event) => voi...

FILE: packages/core/src/text-area/place-holder.ts
  function handlePlaceholder (line 15) | function handlePlaceholder(textarea: TextArea, editor: IDomEditor) {
  function hidePlaceholder (line 46) | function hidePlaceholder(textarea: TextArea, editor: IDomEditor) {

FILE: packages/core/src/text-area/syncSelection.ts
  function editorSelectionToDOM (line 23) | function editorSelectionToDOM(textarea: TextArea, editor: IDomEditor, fo...
  function DOMSelectionToEditor (line 156) | function DOMSelectionToEditor(textarea: TextArea, editor: IDomEditor) {

FILE: packages/core/src/text-area/update-view.ts
  function genElemId (line 22) | function genElemId(id: number) {
  function genRootVnode (line 31) | function genRootVnode(elemId: string, readOnly = false): VNode {
  function genRootElem (line 45) | function genRootElem(elemId: string, readOnly = false): Dom7Array {
  function updateView (line 67) | function updateView(textarea: TextArea, editor: IDomEditor) {

FILE: packages/core/src/to-html/elem2html.ts
  function defaultParser (line 17) | function defaultParser(elemNode: Element, childrenHtml: string, editor: ...
  function getParser (line 27) | function getParser(type: string): ElemToHtmlFnType {
  function elemToHtml (line 32) | function elemToHtml(elemNode: Element, editor: IDomEditor): string {

FILE: packages/core/src/to-html/index.ts
  type styleToHtmlFnType (line 11) | type styleToHtmlFnType = (node: Descendant, elemHtml: string) => string
  constant STYLE_TO_HTML_FN_LIST (line 13) | const STYLE_TO_HTML_FN_LIST: styleToHtmlFnType[] = []
  function registerStyleToHtmlHandler (line 19) | function registerStyleToHtmlHandler(fn: styleToHtmlFnType) {
  type IElemToHtmlRes (line 25) | interface IElemToHtmlRes {
  type ElemToHtmlFnType (line 31) | type ElemToHtmlFnType = (
  constant ELEM_TO_HTML_CONF (line 38) | const ELEM_TO_HTML_CONF: {
  type IElemToHtmlConf (line 42) | interface IElemToHtmlConf {
  function registerElemToHtmlConf (line 51) | function registerElemToHtmlConf(conf: IElemToHtmlConf) {

FILE: packages/core/src/to-html/node2html.ts
  function node2html (line 11) | function node2html(node: Descendant, editor: IDomEditor): string {

FILE: packages/core/src/to-html/text2html.ts
  function textToHtml (line 12) | function textToHtml(textNode: Text, editor: IDomEditor): string {

FILE: packages/core/src/upload/createUploader.ts
  function createUploader (line 11) | function createUploader(config: IUploadConfig): Uppy {

FILE: packages/core/src/upload/interface.ts
  type FilesType (line 8) | type FilesType = { [key: string]: UppyFile<{}, {}> }
  type IUploadConfig (line 13) | interface IUploadConfig {

FILE: packages/core/src/utils/dom.ts
  type DOMPoint (line 85) | type DOMPoint = [Node, number]
  function getFirstVoidChild (line 293) | function getFirstVoidChild(elem: DOMElement): DOMElement | null {
  function walkTextNodes (line 341) | function walkTextNodes(
  type NodeType (line 361) | enum NodeType {
  function getTagName (line 376) | function getTagName($elem: Dom7Array): string {

FILE: packages/core/src/utils/hotkeys.ts
  type KEYS (line 9) | interface KEYS {
  constant HOTKEYS (line 16) | const HOTKEYS: KEYS = {
  constant APPLE_HOTKEYS (line 34) | const APPLE_HOTKEYS: KEYS = {
  constant WINDOWS_HOTKEYS (line 51) | const WINDOWS_HOTKEYS: KEYS = {

FILE: packages/core/src/utils/key.ts
  class Key (line 11) | class Key {
    method constructor (line 14) | constructor() {

FILE: packages/core/src/utils/ua.ts
  constant IS_IOS (line 6) | const IS_IOS =
  constant IS_APPLE (line 12) | const IS_APPLE = typeof navigator !== 'undefined' && /Mac OS X/.test(nav...
  constant IS_FIREFOX (line 14) | const IS_FIREFOX =
  constant IS_FIREFOX_LEGACY (line 17) | const IS_FIREFOX_LEGACY =
  constant IS_SAFARI (line 21) | const IS_SAFARI =
  constant IS_EDGE_LEGACY (line 25) | const IS_EDGE_LEGACY =
  constant IS_CHROME_LEGACY (line 30) | const IS_CHROME_LEGACY =
  constant IS_CHROME (line 34) | const IS_CHROME = typeof navigator !== 'undefined' && /Chrome/i.test(nav...
  constant IS_QQBROWSER (line 37) | const IS_QQBROWSER =
  constant HAS_BEFORE_INPUT_SUPPORT (line 43) | const HAS_BEFORE_INPUT_SUPPORT =

FILE: packages/core/src/utils/util.ts
  type PromiseCallback (line 9) | type PromiseCallback = (value: void) => void | PromiseLike<void>
  function genRandomStr (line 16) | function genRandomStr(prefix: string = 'r'): string {
  function promiseResolveThen (line 20) | function promiseResolveThen(fn: Function) {
  function addQueryToUrl (line 29) | function addQueryToUrl(url: string, data: object): string {
  function replaceHtmlSpecialSymbols (line 60) | function replaceHtmlSpecialSymbols(str: string) {
  function deReplaceHtmlSpecialSymbols (line 81) | function deReplaceHtmlSpecialSymbols(str: string) {

FILE: packages/core/src/utils/vdom.ts
  type PatchFn (line 21) | type PatchFn = (oldVnode: VNode | Element, vnode: VNode) => VNode
  function genPatchFn (line 27) | function genPatchFn(): PatchFn {
  constant DATA_PRESERVE_KEYS (line 41) | const DATA_PRESERVE_KEYS = ['props', 'attrs', 'style', 'dataset', 'on', ...
  function normalizeVnodeData (line 47) | function normalizeVnodeData(vnode: VNode) {
  function addVnodeProp (line 94) | function addVnodeProp(vnode: VNode, newProp: Props) {
  function addVnodeDataset (line 107) | function addVnodeDataset(vnode: VNode, newDataset: Dataset) {
  function addVnodeStyle (line 120) | function addVnodeStyle(vnode: VNode, newStyle: VNodeStyle) {

FILE: packages/core/src/utils/weak-maps.ts
  constant EDITOR_TO_TEXTAREA (line 20) | const EDITOR_TO_TEXTAREA = new WeakMap<IDomEditor, TextArea>()
  constant TEXTAREA_TO_EDITOR (line 21) | const TEXTAREA_TO_EDITOR = new WeakMap<TextArea, IDomEditor>()
  constant TOOLBAR_TO_EDITOR (line 24) | const TOOLBAR_TO_EDITOR = new WeakMap<Toolbar, IDomEditor>()
  constant EDITOR_TO_TOOLBAR (line 25) | const EDITOR_TO_TOOLBAR = new WeakMap<IDomEditor, Toolbar>()
  constant HOVER_BAR_TO_EDITOR (line 26) | const HOVER_BAR_TO_EDITOR = new WeakMap<HoverBar, IDomEditor>()
  constant EDITOR_TO_HOVER_BAR (line 27) | const EDITOR_TO_HOVER_BAR = new WeakMap<IDomEditor, HoverBar>()
  constant BAR_ITEM_TO_EDITOR (line 28) | const BAR_ITEM_TO_EDITOR = new WeakMap<IBarItem, IDomEditor>()
  constant EDITOR_TO_PANEL_AND_MODAL (line 29) | const EDITOR_TO_PANEL_AND_MODAL = new WeakMap<IDomEditor, Set<PanelAndMo...
  constant PANEL_OR_MODAL_TO_EDITOR (line 30) | const PANEL_OR_MODAL_TO_EDITOR = new WeakMap<PanelAndModal, IDomEditor>()
  constant EDITOR_TO_CONFIG (line 33) | const EDITOR_TO_CONFIG = new WeakMap<IDomEditor, IEditorConfig>()
  constant IS_FIRST_PATCH (line 36) | const IS_FIRST_PATCH = new WeakMap<TextArea, boolean>()
  constant TEXTAREA_TO_PATCH_FN (line 37) | const TEXTAREA_TO_PATCH_FN = new WeakMap<TextArea, PatchFn>()
  constant TEXTAREA_TO_VNODE (line 38) | const TEXTAREA_TO_VNODE = new WeakMap<TextArea, VNode>()
  constant NODE_TO_INDEX (line 44) | const NODE_TO_INDEX: WeakMap<Node, number> = new WeakMap()
  constant NODE_TO_PARENT (line 45) | const NODE_TO_PARENT: WeakMap<Node, Ancestor> = new WeakMap()
  constant EDITOR_TO_ELEMENT (line 51) | const EDITOR_TO_ELEMENT: WeakMap<Editor, HTMLElement> = new WeakMap()
  constant EDITOR_TO_PLACEHOLDER (line 52) | const EDITOR_TO_PLACEHOLDER: WeakMap<Editor, string> = new WeakMap()
  constant ELEMENT_TO_NODE (line 53) | const ELEMENT_TO_NODE: WeakMap<HTMLElement, Node> = new WeakMap()
  constant KEY_TO_ELEMENT (line 54) | const KEY_TO_ELEMENT: WeakMap<Key, HTMLElement> = new WeakMap()
  constant NODE_TO_ELEMENT (line 55) | const NODE_TO_ELEMENT: WeakMap<Node, HTMLElement> = new WeakMap()
  constant NODE_TO_KEY (line 56) | const NODE_TO_KEY: WeakMap<Node, Key> = new WeakMap()
  constant EDITOR_TO_WINDOW (line 57) | const EDITOR_TO_WINDOW: WeakMap<Editor, Window> = new WeakMap()
  constant IS_FOCUSED (line 62) | const IS_FOCUSED: WeakMap<Editor, boolean> = new WeakMap()
  constant IS_DRAGGING (line 63) | const IS_DRAGGING: WeakMap<Editor, boolean> = new WeakMap()
  constant IS_CLICKING (line 64) | const IS_CLICKING: WeakMap<Editor, boolean> = new WeakMap()
  constant CHANGING_NODE_PATH (line 73) | const CHANGING_NODE_PATH: WeakMap<Editor, Path> = new WeakMap()
  constant EDITOR_TO_SELECTION (line 76) | const EDITOR_TO_SELECTION: WeakMap<Editor, Range> = new WeakMap()
  constant EDITOR_TO_EMITTER (line 79) | const EDITOR_TO_EMITTER: WeakMap<Editor, Emitter> = new WeakMap()
  constant EDITOR_TO_CAN_PASTE (line 82) | const EDITOR_TO_CAN_PASTE: WeakMap<Editor, boolean> = new WeakMap()

FILE: packages/custom-types.d.ts
  type PureText (line 33) | type PureText = {
  type CustomText (line 37) | type CustomText = PureText | StyledText | FontSizeAndFamilyText | ColorText
  type BaseElement (line 39) | type BaseElement = {
  type CustomElement (line 44) | type CustomElement =
  type CustomTypes (line 69) | interface CustomTypes {

FILE: packages/editor/__tests__/create.test.ts
  function customCreateEditor (line 9) | function customCreateEditor(config: Partial<ICreateEditorOption> = {}) {
  function customCreateToolbar (line 22) | function customCreateToolbar(config: Partial<ICreateToolbarOption> = {}) {

FILE: packages/editor/demo/js/custom-elem.js
  class MyNav (line 62) | class MyNav extends HTMLElement {
    method constructor (line 63) | constructor() {
    method attributeChangedCallback (line 126) | attributeChangedCallback(name, oldValue, newValue) {
  constant MENU_CONF (line 140) | const MENU_CONF = [
  class MyMenu (line 259) | class MyMenu extends HTMLElement {
    method constructor (line 260) | constructor() {

FILE: packages/editor/demo/js/huge-content.js
  function deepClone (line 2) | function deepClone(obj) {

FILE: packages/editor/examples/js/huge-content.js
  function deepClone (line 2) | function deepClone(obj) {

FILE: packages/editor/src/Boot.ts
  type PluginType (line 41) | type PluginType = <T extends IDomEditor>(editor: T) => T
  class Boot (line 43) | class Boot {
    method constructor (line 44) | constructor() {
    method setEditorConfig (line 50) | static setEditorConfig(newConfig: Partial<IEditorConfig> = {}) {
    method setSimpleEditorConfig (line 57) | static setSimpleEditorConfig(newConfig: Partial<IEditorConfig> = {}) {
    method setToolbarConfig (line 66) | static setToolbarConfig(newConfig: Partial<IToolbarConfig> = {}) {
    method setSimpleToolbarConfig (line 73) | static setSimpleToolbarConfig(newConfig: Partial<IToolbarConfig> = {}) {
    method registerPlugin (line 82) | static registerPlugin(plugin: PluginType) {
    method registerMenu (line 88) | static registerMenu(menuConf: IRegisterMenuConf, customConfig?: { [key...
    method registerRenderElem (line 93) | static registerRenderElem(renderElemConf: IRenderElemConf) {
    method registerRenderStyle (line 98) | static registerRenderStyle(fn: RenderStyleFnType) {
    method registerElemToHtml (line 103) | static registerElemToHtml(elemToHtmlConf: IElemToHtmlConf) {
    method registerStyleToHtml (line 108) | static registerStyleToHtml(fn: styleToHtmlFnType) {
    method registerPreParseHtml (line 113) | static registerPreParseHtml(preParseHtmlConf: IPreParseHtmlConf) {
    method registerParseElemHtml (line 118) | static registerParseElemHtml(parseElemHtmlConf: IParseElemHtmlConf) {
    method registerParseStyleHtml (line 123) | static registerParseStyleHtml(fn: ParseStyleHtmlFnType) {
    method registerModule (line 128) | static registerModule(module: Partial<IModuleConf>) {

FILE: packages/editor/src/constants/svg.ts
  constant INDENT_RIGHT_SVG (line 13) | const INDENT_RIGHT_SVG =
  constant JUSTIFY_LEFT_SVG (line 17) | const JUSTIFY_LEFT_SVG =
  constant IMAGE_SVG (line 21) | const IMAGE_SVG =
  constant MORE_SVG (line 25) | const MORE_SVG =
  constant VIDEO_SVG (line 29) | const VIDEO_SVG =

FILE: packages/editor/src/create.ts
  type ICreateEditorOption (line 18) | interface ICreateEditorOption {
  type ICreateToolbarOption (line 26) | interface ICreateToolbarOption {
  function createEditor (line 36) | function createEditor(option: Partial<ICreateEditorOption> = {}): IDomEd...
  function createToolbar (line 65) | function createToolbar(option: ICreateToolbarOption): Toolbar {

FILE: packages/editor/src/init-default-config/config/hoverbar.ts
  constant COMMON_HOVERBAR_KEYS (line 6) | const COMMON_HOVERBAR_KEYS = {
  function genDefaultHoverbarKeys (line 44) | function genDefaultHoverbarKeys() {
  function genSimpleHoverbarKeys (line 66) | function genSimpleHoverbarKeys() {

FILE: packages/editor/src/init-default-config/config/index.ts
  function getDefaultEditorConfig (line 9) | function getDefaultEditorConfig() {
  function getSimpleEditorConfig (line 15) | function getSimpleEditorConfig() {
  function getDefaultToolbarConfig (line 21) | function getDefaultToolbarConfig() {
  function getSimpleToolbarConfig (line 27) | function getSimpleToolbarConfig() {

FILE: packages/editor/src/init-default-config/config/toolbar.ts
  function genDefaultToolbarKeys (line 15) | function genDefaultToolbarKeys() {
  function genSimpleToolbarKeys (line 89) | function genSimpleToolbarKeys() {

FILE: packages/editor/src/register-builtin-modules/register.ts
  function registerModule (line 9) | function registerModule(module: Partial<IModuleConf>) {

FILE: packages/editor/src/utils/browser-polyfill.ts
  function globalThisPolyfill (line 25) | function globalThisPolyfill() {
  function AggregateErrorPolyfill (line 33) | function AggregateErrorPolyfill() {

FILE: packages/list-module/src/constants/svg.ts
  constant BULLETED_LIST_SVG (line 13) | const BULLETED_LIST_SVG =
  constant NUMBERED_LIST_SVG (line 17) | const NUMBERED_LIST_SVG =

FILE: packages/list-module/src/module/custom-types.ts
  type ListItemElement (line 10) | type ListItemElement = {

FILE: packages/list-module/src/module/elem-to-html.ts
  function getStartContainerTagNumber (line 15) | function getStartContainerTagNumber(elem: Element): number {
  function getEndContainerTagNumber (line 68) | function getEndContainerTagNumber(elem: Element): number {
  constant CONTAINER_TAG_STACK (line 118) | const CONTAINER_TAG_STACK: Array<string> = []
  function elemToHtml (line 120) | function elemToHtml(

FILE: packages/list-module/src/module/menu/BaseMenu.ts
  method getListNode (line 17) | private getListNode(editor: IDomEditor): Node | null {
  method getValue (line 22) | getValue(editor: IDomEditor): string | boolean {
  method isActive (line 26) | isActive(editor: IDomEditor): boolean {
  method isDisabled (line 33) | isDisabled(editor: IDomEditor): boolean {
  method exec (line 48) | exec(editor: IDomEditor, value: string | boolean): void {

FILE: packages/list-module/src/module/menu/BulletedListMenu.ts
  class BulletedListMenu (line 10) | class BulletedListMenu extends BaseMenu {

FILE: packages/list-module/src/module/menu/NumberedListMenu.ts
  class NumberedListMenu (line 10) | class NumberedListMenu extends BaseMenu {

FILE: packages/list-module/src/module/menu/index.ts
  method factory (line 11) | factory() {
  method factory (line 18) | factory() {

FILE: packages/list-module/src/module/parse-elem-html.ts
  function getOrdered (line 16) | function getOrdered($elem: Dom7Array): boolean {
  function getLevel (line 27) | function getLevel($elem: Dom7Array): number {
  function parseItemHtml (line 42) | function parseItemHtml(
  function parseListHtml (line 77) | function parseListHtml(

FILE: packages/list-module/src/module/plugin.ts
  function getTopSelectedElemsBySelection (line 14) | function getTopSelectedElemsBySelection(editor: IDomEditor) {
  function withList (line 21) | function withList<T extends IDomEditor>(editor: T): T {

FILE: packages/list-module/src/module/render-elem.tsx
  function genPreSymbol (line 16) | function genPreSymbol(level = 0): string {
  function getOrderedItemNumber (line 39) | function getOrderedItemNumber(editor: IDomEditor, elem: SlateElement): n...
  function getListItemColor (line 83) | function getListItemColor(elem: SlateElement): string {
  function renderListElem (line 100) | function renderListElem(

FILE: packages/list-module/src/utils/dom.ts
  function getTagName (line 36) | function getTagName($elem: Dom7Array): string {

FILE: packages/list-module/src/utils/maps.ts
  constant ELEM_TO_EDITOR (line 9) | const ELEM_TO_EDITOR = new WeakMap<SlateElement, IDomEditor>()

FILE: packages/table-module/__tests__/menu/delete-col.test.ts
  function setEditorSelection (line 8) | function setEditorSelection(

FILE: packages/table-module/__tests__/menu/delete-row.test.ts
  function setEditorSelection (line 8) | function setEditorSelection(

FILE: packages/table-module/__tests__/menu/delete-table.test.ts
  function setEditorSelection (line 7) | function setEditorSelection(

FILE: packages/table-module/__tests__/menu/full-width.test.ts
  function setEditorSelection (line 8) | function setEditorSelection(

FILE: packages/table-module/__tests__/menu/insert-col.test.ts
  function setEditorSelection (line 8) | function setEditorSelection(

FILE: packages/table-module/__tests__/menu/insert-row.test.ts
  function setEditorSelection (line 8) | function setEditorSelection(

FILE: packages/table-module/__tests__/menu/insert-table.test.ts
  function setEditorSelection (line 9) | function setEditorSelection(

FILE: packages/table-module/__tests__/menu/table-header.test.ts
  function setEditorSelection (line 8) | function setEditorSelection(

FILE: packages/table-module/src/constants/svg.ts
  constant TABLE_SVG (line 13) | const TABLE_SVG =
  constant TRASH_SVG (line 17) | const TRASH_SVG =
  constant ADD_ROW_SVG (line 21) | const ADD_ROW_SVG =
  constant DEL_ROW_SVG (line 25) | const DEL_ROW_SVG =
  constant ADD_COL_SVG (line 29) | const ADD_COL_SVG =
  constant DEL_COL_SVG (line 33) | const DEL_COL_SVG =
  constant TABLE_HEADER_SVG (line 37) | const TABLE_HEADER_SVG =
  constant FULL_WIDTH_SVG (line 41) | const FULL_WIDTH_SVG =

FILE: packages/table-module/src/module/custom-types.ts
  type TableCellElement (line 10) | type TableCellElement = {
  type TableRowElement (line 19) | type TableRowElement = {
  type TableElement (line 24) | type TableElement = {

FILE: packages/table-module/src/module/elem-to-html.ts
  function tableToHtml (line 9) | function tableToHtml(elemNode: Element, childrenHtml: string): string {
  function tableRowToHtml (line 15) | function tableRowToHtml(elem: Element, childrenHtml: string): string {
  function tableCellToHtml (line 19) | function tableCellToHtml(cellNode: Element, childrenHtml: string): string {

FILE: packages/table-module/src/module/helpers.ts
  function getFirstRowCells (line 13) | function getFirstRowCells(tableNode: TableElement): TableCellElement[] {
  function isTableWithHeader (line 25) | function isTableWithHeader(tableNode: TableElement): boolean {
  function isCellInFirstRow (line 35) | function isCellInFirstRow(editor: IDomEditor, cellNode: TableCellElement...

FILE: packages/table-module/src/module/menu/DeleteCol.ts
  class DeleteCol (line 11) | class DeleteCol implements IButtonMenu {
    method getValue (line 16) | getValue(editor: IDomEditor): string | boolean {
    method isActive (line 21) | isActive(editor: IDomEditor): boolean {
    method isDisabled (line 26) | isDisabled(editor: IDomEditor): boolean {
    method exec (line 39) | exec(editor: IDomEditor, value: string | boolean) {

FILE: packages/table-module/src/module/menu/DeleteRow.ts
  class DeleteRow (line 10) | class DeleteRow implements IButtonMenu {
    method getValue (line 15) | getValue(editor: IDomEditor): string | boolean {
    method isActive (line 20) | isActive(editor: IDomEditor): boolean {
    method isDisabled (line 25) | isDisabled(editor: IDomEditor): boolean {
    method exec (line 38) | exec(editor: IDomEditor, value: string | boolean) {

FILE: packages/table-module/src/module/menu/DeleteTable.ts
  class DeleteTable (line 10) | class DeleteTable implements IButtonMenu {
    method getValue (line 15) | getValue(editor: IDomEditor): string | boolean {
    method isActive (line 20) | isActive(editor: IDomEditor): boolean {
    method isDisabled (line 25) | isDisabled(editor: IDomEditor): boolean {
    method exec (line 36) | exec(editor: IDomEditor, value: string | boolean) {

FILE: packages/table-module/src/module/menu/FullWidth.ts
  class TableFullWidth (line 11) | class TableFullWidth implements IButtonMenu {
    method getValue (line 17) | getValue(editor: IDomEditor): string | boolean {
    method isActive (line 23) | isActive(editor: IDomEditor): boolean {
    method isDisabled (line 27) | isDisabled(editor: IDomEditor): boolean {
    method exec (line 40) | exec(editor: IDomEditor, value: string | boolean) {

FILE: packages/table-module/src/module/menu/InsertCol.ts
  class InsertCol (line 13) | class InsertCol implements IButtonMenu {
    method getValue (line 18) | getValue(editor: IDomEditor): string | boolean {
    method isActive (line 23) | isActive(editor: IDomEditor): boolean {
    method isDisabled (line 28) | isDisabled(editor: IDomEditor): boolean {
    method exec (line 41) | exec(editor: IDomEditor, value: string | boolean) {

FILE: packages/table-module/src/module/menu/InsertRow.ts
  class InsertRow (line 11) | class InsertRow implements IButtonMenu {
    method getValue (line 16) | getValue(editor: IDomEditor): string | boolean {
    method isActive (line 21) | isActive(editor: IDomEditor): boolean {
    method isDisabled (line 26) | isDisabled(editor: IDomEditor): boolean {
    method exec (line 39) | exec(editor: IDomEditor, value: string | boolean) {

FILE: packages/table-module/src/module/menu/InsertTable.ts
  function genTableNode (line 13) | function genTableNode(rowNum: number, colNum: number): TableElement {
  function genDomID (line 47) | function genDomID(): string {
  class InsertTable (line 51) | class InsertTable implements IDropPanelMenu {
    method getValue (line 58) | getValue(editor: IDomEditor): string | boolean {
    method isActive (line 63) | isActive(editor: IDomEditor): boolean {
    method exec (line 68) | exec(editor: IDomEditor, value: string | boolean) {
    method isDisabled (line 73) | isDisabled(editor: IDomEditor): boolean {
    method getPanelContentElem (line 96) | getPanelContentElem(editor: IDomEditor): DOMElement {
    method insertTable (line 160) | private insertTable(editor: IDomEditor, rowNumStr: string, colNumStr: ...

FILE: packages/table-module/src/module/menu/TableHeader.ts
  class TableHeader (line 12) | class TableHeader implements IButtonMenu {
    method getValue (line 18) | getValue(editor: IDomEditor): string | boolean {
    method isActive (line 25) | isActive(editor: IDomEditor): boolean {
    method isDisabled (line 29) | isDisabled(editor: IDomEditor): boolean {
    method exec (line 42) | exec(editor: IDomEditor, value: string | boolean) {

FILE: packages/table-module/src/module/menu/index.ts
  method factory (line 17) | factory() {
  method factory (line 24) | factory() {
  method factory (line 31) | factory() {
  method factory (line 38) | factory() {
  method factory (line 45) | factory() {
  method factory (line 52) | factory() {
  method factory (line 59) | factory() {
  method factory (line 66) | factory() {

FILE: packages/table-module/src/module/parse-elem-html.ts
  function parseCellHtml (line 11) | function parseCellHtml(
  function parseRowHtml (line 49) | function parseRowHtml(
  function parseTableHtml (line 66) | function parseTableHtml(

FILE: packages/table-module/src/module/plugin.ts
  function deleteHandler (line 21) | function deleteHandler(newEditor: IDomEditor): boolean {
  function isTableLocation (line 45) | function isTableLocation(editor: IDomEditor, location: Location): boolean {
  function withTable (line 60) | function withTable<T extends IDomEditor>(editor: T): T {

FILE: packages/table-module/src/module/pre-parse-html.ts
  function preParse (line 12) | function preParse(tableElem: DOMElement): DOMElement {

FILE: packages/table-module/src/module/render-elem/render-cell.tsx
  function onMouseDown (line 22) | function onMouseDown(event: Event) {
  function onMouseUp (line 44) | function onMouseUp(event: Event) {
  function renderTableCell (line 74) | function renderTableCell(

FILE: packages/table-module/src/module/render-elem/render-row.tsx
  function renderTableRow (line 10) | function renderTableRow(

FILE: packages/table-module/src/module/render-elem/render-table.tsx
  function getContentEditable (line 17) | function getContentEditable(editor: IDomEditor, tableElem: SlateElement)...
  function renderTable (line 44) | function renderTable(elemNode: SlateElement, children: VNode[] | null, e...

FILE: packages/table-module/src/utils/dom.ts
  function getTagName (line 42) | function getTagName($elem: Dom7Array): string {
  function getStyleValue (line 52) | function getStyleValue($elem: Dom7Array, styleKey: string): string {

FILE: packages/table-module/src/utils/util.ts
  function genRandomStr (line 13) | function genRandomStr(prefix: string = 'r'): string {

FILE: packages/upload-image-module/__tests__/upload-files.test.ts
  function mockFile (line 5) | function mockFile(filename: string) {

FILE: packages/upload-image-module/src/constants/svg.ts
  constant UPLOAD_IMAGE_SVG (line 13) | const UPLOAD_IMAGE_SVG =

FILE: packages/upload-image-module/src/module/menu/UploadImageMenu.ts
  class UploadImage (line 13) | class UploadImage implements IButtonMenu {
    method getValue (line 18) | getValue(editor: IDomEditor): string | boolean {
    method isActive (line 23) | isActive(editor: IDomEditor): boolean {
    method isDisabled (line 28) | isDisabled(editor: IDomEditor): boolean {
    method getMenuConfig (line 32) | private getMenuConfig(editor: IDomEditor): IUploadConfigForImage {
    method exec (line 37) | exec(editor: IDomEditor, value: string | boolean) {

FILE: packages/upload-image-module/src/module/menu/config.ts
  type InsertFn (line 8) | type InsertFn = (src: string, alt: string, href: string) => void
  type IUploadConfigForImage (line 11) | type IUploadConfigForImage = IUploadConfig & {
  function genUploadImageConfig (line 24) | function genUploadImageConfig(): IUploadConfigForImage {

FILE: packages/upload-image-module/src/module/menu/index.ts
  method factory (line 11) | factory() {

FILE: packages/upload-image-module/src/module/plugin.ts
  function withUploadImage (line 10) | function withUploadImage<T extends IDomEditor>(editor: T): T {

FILE: packages/upload-image-module/src/module/upload-images.ts
  constant EDITOR_TO_UPPY_MAP (line 12) | const EDITOR_TO_UPPY_MAP = new WeakMap<IDomEditor, Uppy>()
  function getUppy (line 18) | function getUppy(editor: IDomEditor): Uppy {
  function getMenuConfig (line 91) | function getMenuConfig(editor: IDomEditor) {
  function insertBase64 (line 100) | async function insertBase64(editor: IDomEditor, file: File) {
  function uploadFile (line 121) | async function uploadFile(editor: IDomEditor, file: File) {

FILE: packages/video-module/__tests__/menu/insert-video-menu.test.ts
  function setEditorSelection (line 11) | function setEditorSelection(

FILE: packages/video-module/__tests__/menu/upload-video-menu.test.ts
  function setEditorSelection (line 12) | function setEditorSelection(

FILE: packages/video-module/src/constants/svg.ts
  constant VIDEO_SVG (line 13) | const VIDEO_SVG =
  constant UPLOAD_VIDEO_SVG (line 17) | const UPLOAD_VIDEO_SVG =

FILE: packages/video-module/src/module/custom-types.ts
  type EmptyText (line 8) | type EmptyText = {
  type VideoElement (line 12) | type VideoElement = {

FILE: packages/video-module/src/module/elem-to-html.ts
  function videoToHtml (line 10) | function videoToHtml(elemNode: Element, childrenHtml?: string): string {

FILE: packages/video-module/src/module/helper/upload-videos.ts
  function getMenuConfig (line 11) | function getMenuConfig(editor: IDomEditor): IUploadConfigForVideo {
  constant EDITOR_TO_UPPY_MAP (line 17) | const EDITOR_TO_UPPY_MAP = new WeakMap<IDomEditor, Uppy>()
  function getUppy (line 23) | function getUppy(editor: IDomEditor): Uppy {
  function uploadFile (line 90) | async function uploadFile(editor: IDomEditor, file: File) {

FILE: packages/video-module/src/module/menu/EditVideoSizeMenu.ts
  function genDomID (line 22) | function genDomID(): string {
  class EditorVideoSizeMenu (line 26) | class EditorVideoSizeMenu implements IModalMenu {
    method getSelectedVideoNode (line 36) | private getSelectedVideoNode(editor: IDomEditor): SlateNode | null {
    method getValue (line 40) | getValue(editor: IDomEditor): string | boolean {
    method isActive (line 45) | isActive(editor: IDomEditor): boolean {
    method exec (line 50) | exec(editor: IDomEditor, value: string | boolean) {
    method isDisabled (line 55) | isDisabled(editor: IDomEditor): boolean {
    method getModalPositionNode (line 66) | getModalPositionNode(editor: IDomEditor): SlateNode | null {
    method getModalContentElem (line 70) | getModalContentElem(editor: IDomEditor): DOMElement {

FILE: packages/video-module/src/module/menu/InsertVideoMenu.ts
  function genDomID (line 23) | function genDomID(): string {
  class InsertVideoMenu (line 27) | class InsertVideoMenu implements IModalMenu {
    method getValue (line 38) | getValue(editor: IDomEditor): string | boolean {
    method isActive (line 43) | isActive(editor: IDomEditor): boolean {
    method exec (line 48) | exec(editor: IDomEditor, value: string | boolean) {
    method isDisabled (line 53) | isDisabled(editor: IDomEditor): boolean {
    method getModalPositionNode (line 71) | getModalPositionNode(editor: IDomEditor): Node | null {
    method getModalContentElem (line 75) | getModalContentElem(editor: IDomEditor): DOMElement {

FILE: packages/video-module/src/module/menu/UploadVideoMenu.ts
  class UploadVideoMenu (line 14) | class UploadVideoMenu implements IButtonMenu {
    method getValue (line 19) | getValue(editor: IDomEditor): string | boolean {
    method isActive (line 24) | isActive(editor: IDomEditor): boolean {
    method exec (line 29) | exec(editor: IDomEditor, value: string | boolean) {
    method isDisabled (line 57) | isDisabled(editor: IDomEditor): boolean {
    method getMenuConfig (line 75) | private getMenuConfig(editor: IDomEditor): IUploadConfigForVideo {

FILE: packages/video-module/src/module/menu/config.ts
  type InsertFn (line 9) | type InsertFn = (src: string, poster: string) => void
  type IUploadConfigForVideo (line 12) | type IUploadConfigForVideo = IUploadConfig & {
  function genUploadVideoMenuConfig (line 22) | function genUploadVideoMenuConfig(): IUploadConfigForVideo {
  function genInsertVideoMenuConfig (line 73) | function genInsertVideoMenuConfig() {

FILE: packages/video-module/src/module/menu/index.ts
  method factory (line 14) | factory() {
  method factory (line 25) | factory() {
  method factory (line 36) | factory() {

FILE: packages/video-module/src/module/parse-elem-html.ts
  function genVideoElem (line 11) | function genVideoElem(
  function parseHtml (line 27) | function parseHtml(elem: DOMElement, children: Descendant[], editor: IDo...

FILE: packages/video-module/src/module/plugin.ts
  function withVideo (line 10) | function withVideo<T extends IDomEditor>(editor: T): T {

FILE: packages/video-module/src/module/pre-parse-html.ts
  function preParse (line 12) | function preParse(elem: DOMElement): DOMElement {

FILE: packages/video-module/src/module/render-elem.tsx
  function renderVideo (line 12) | function renderVideo(elemNode: Element, children: VNode[] | null, editor...

FILE: packages/video-module/src/utils/dom.ts
  function getTagName (line 25) | function getTagName($elem: Dom7Array): string {
  function genSizeStyledIframeHtml (line 37) | function genSizeStyledIframeHtml(

FILE: packages/video-module/src/utils/util.ts
  function genRandomStr (line 13) | function genRandomStr(prefix: string = 'r'): string {
  function replaceSymbols (line 17) | function replaceSymbols(str: string) {

FILE: scripts/release-tag.js
  constant DEFAULT_RELEASE_COMMIT_MESSAGE (line 3) | const DEFAULT_RELEASE_COMMIT_MESSAGE = 'chore: release tag'
  function command (line 5) | function command(command) {
  function run (line 16) | async function run(commitMsg = DEFAULT_RELEASE_COMMIT_MESSAGE) {

FILE: tests/setup/index.ts
  method clearData (line 14) | clearData() {}
  method getData (line 15) | getData(type: string) {
  method setData (line 19) | setData() {}
  method files (line 20) | get files() {

FILE: tests/utils/create-editor.ts
  function createEditor (line 7) | function createEditor(options: any = {}) {

FILE: tests/utils/create-toolbar.ts
  function createToolbar (line 7) | function createToolbar(editor: any, config: any = {}) {
Condensed preview — 687 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (1,177K chars).
[
  {
    "path": ".browserslistrc",
    "chars": 43,
    "preview": "defaults\nnot IE 11\nmaintained node versions"
  },
  {
    "path": ".cz-config.js",
    "chars": 1462,
    "preview": "module.exports = {\n  types: [\n    {\n      value: 'WIP',\n      name: '💡  WIP: Work in progress',\n    },\n    {\n      value"
  },
  {
    "path": ".eslintignore",
    "chars": 32,
    "preview": "node_modules/*\ndist/\nlib/\n*.html"
  },
  {
    "path": ".eslintrc.js",
    "chars": 840,
    "preview": "module.exports = {\n  env: {\n    browser: true,\n    es6: true,\n    mocha: true,\n    jest: true,\n    node: true,\n  },\n  ex"
  },
  {
    "path": ".github/FUNDING.yml",
    "chars": 161,
    "preview": "# These are supported funding model platforms\n\ngithub: # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [u"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/bug.md",
    "chars": 485,
    "preview": "---\nname: 提交 bug\nabout: 请大家一定要按照该模板填写,以方便我们更快复现,否则该 issue 将不予受理!\n---\n\n## bug 描述\n\n*请输入内容……*\n\n## 你预期的样子是?\n\n*请输入内容……*\n\n## 系"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/feature.md",
    "chars": 215,
    "preview": "---\nname: 建议增加新功能\nabout: 请按照该模板填写,以便我们能真正了解你的需求,否则该 issue 将不予受理!\n---\n\n## 功能描述\n\n*请输入内容……*\n\n## 提炼几个功能点\n\n- 功能1\n- 功能2\n- 功能3\n"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/question.md",
    "chars": 268,
    "preview": "---\nname: 使用时遇到了问题(非 bug)\nabout: 请按照该模板填写,以便我们能真正了解你的问题,否则该 issue 将不予受理!\n---\n\n## 问题描述\n\n*请输入遇到的问题...*\n\n## wangEditor 版本\n\n"
  },
  {
    "path": ".github/workflows/deploy-demos.yml",
    "chars": 1635,
    "preview": "# This workflow will do a clean install of node dependencies, build the source code and run tests across different versi"
  },
  {
    "path": ".github/workflows/deploy-examples.yml.bak",
    "chars": 2307,
    "preview": "# This workflow will do a clean install of node dependencies, build the source code and run tests across different versi"
  },
  {
    "path": ".github/workflows/e2e.yml",
    "chars": 1291,
    "preview": "# This workflow will do a clean install of node dependencies, build the source code and run tests across different versi"
  },
  {
    "path": ".github/workflows/release.yml",
    "chars": 916,
    "preview": "name: Release\n\non:\n  push:\n    tags:\n      - 'v*'\n\njobs:\n  release:\n    runs-on: ubuntu-latest\n    strategy:\n      max-p"
  },
  {
    "path": ".github/workflows/test.yml",
    "chars": 1069,
    "preview": "# This workflow will do a clean install of node dependencies, build the source code and run tests across different versi"
  },
  {
    "path": ".gitignore",
    "chars": 1818,
    "preview": "# Logs\nlogs\n*.log\nnpm-debug.log*\nyarn-debug.log*\nyarn-error.log*\nlerna-debug.log*\n\n# Diagnostic reports (https://nodejs."
  },
  {
    "path": ".npmignore",
    "chars": 17,
    "preview": ".github/\n.vscode\n"
  },
  {
    "path": ".prettierrc.js",
    "chars": 485,
    "preview": "module.exports = {\n  // 箭头函数只有一个参数的时候可以忽略括号\n  arrowParens: 'avoid',\n  // 括号内部不要出现空格\n  bracketSpacing: true,\n  // 行结束符使用 "
  },
  {
    "path": ".vscode/settings.json",
    "chars": 933,
    "preview": "{\n    \"editor.formatOnSave\": true,\n    \"cSpell.words\": [\n      \"beforeinput\",\n      \"bodyparser\",\n      \"browserslist\",\n"
  },
  {
    "path": ".yarnrc",
    "chars": 42,
    "preview": "registry \"https://registry.npm.taobao.org\""
  },
  {
    "path": "CHANGELOG.md",
    "chars": 446,
    "preview": "# Changelog Link\n- [basic-modules](./packages/basic-modules/CHANGELOG.md)\n- [code-highlight](./packages/code-highlight/C"
  },
  {
    "path": "LICENSE",
    "chars": 1082,
    "preview": "MIT License\n\nCopyright (c) 2021 - present wangEditor-team\n\nPermission is hereby granted, free of charge, to any person o"
  },
  {
    "path": "README-en.md",
    "chars": 480,
    "preview": "# wangEditor 5\n\n[中文](./README.md)\n\n## Introduction\n\nOpen source web rich text editor, run right out of the box. Support "
  },
  {
    "path": "README.md",
    "chars": 342,
    "preview": "# wangEditor 5\n\n[English](./README-en.md)\n\n## 介绍\n\n开源 Web 富文本编辑器,开箱即用,配置简单。支持 JS Vue React 。\n\n- [文档](https://www.wangedit"
  },
  {
    "path": "babel.config.json",
    "chars": 443,
    "preview": "{\n  \"presets\": [\n    [\n      \"@babel/preset-env\",\n      {\n        \"modules\": false,\n        \"useBuiltIns\": \"usage\",\n    "
  },
  {
    "path": "build/build-all.sh",
    "chars": 761,
    "preview": "#!/bin/bash\n\n## 一键打包所有 package\n\n# 获取 yarn dev/build 类型\nbuildType=build\nif [ -n \"$1\" ]; then  \n  buildType=$1\nfi\n\ncd ./pa"
  },
  {
    "path": "build/config/common.js",
    "chars": 1522,
    "preview": "/**\n * @description rollup common config\n * @author wangfupeng\n */\n\nimport path from 'path'\nimport commonjs from '@rollu"
  },
  {
    "path": "build/config/dev.js",
    "chars": 577,
    "preview": "/**\n * @description rollup dev config\n * @author wangfupeng\n */\n\nimport postcss from 'rollup-plugin-postcss'\nimport auto"
  },
  {
    "path": "build/config/prd.js",
    "chars": 1153,
    "preview": "/**\n * @description rollup prd config\n * @author wangfupeng\n */\n\nimport babel from '@rollup/plugin-babel'\nimport postcss"
  },
  {
    "path": "build/create-rollup-config.js",
    "chars": 1061,
    "preview": "/**\n * @description 创建 rollup 配置\n * @author wangfupeng\n */\n\nimport { merge } from 'lodash'\nimport { visualizer } from 'r"
  },
  {
    "path": "commitlint.config.js",
    "chars": 88,
    "preview": "module.exports = {\n  extends: ['cz'],\n  rules: {\n    'type-empty': [2, 'never'],\n  },\n}\n"
  },
  {
    "path": "cypress/cypress.d.ts",
    "chars": 374,
    "preview": "/// <reference types=\"cypress\" />\n\ndeclare namespace Cypress {\n  interface CustomWindow extends Window {}\n\n  interface C"
  },
  {
    "path": "cypress/fixtures/example.json",
    "chars": 155,
    "preview": "{\n  \"name\": \"Using fixtures to represent data\",\n  \"email\": \"hello@cypress.io\",\n  \"body\": \"Fixtures are a great way to mo"
  },
  {
    "path": "cypress/integration/editor.spec.ts",
    "chars": 357,
    "preview": "describe('Basic Editor', () => {\n  it('create editor', () => {\n    cy.visit('/examples/default-mode.html')\n\n    cy.get('"
  },
  {
    "path": "cypress/plugins/index.ts",
    "chars": 817,
    "preview": "/// <reference types=\"cypress\" />\n// ***********************************************************\n// This example plugins"
  },
  {
    "path": "cypress/support/commands.ts",
    "chars": 108,
    "preview": "Cypress.Commands.add('getByClass', (selector, ...args) => {\n  return cy.get(`.w-e-${selector}`, ...args)\n})\n"
  },
  {
    "path": "cypress/support/index.ts",
    "chars": 20,
    "preview": "import './commands'\n"
  },
  {
    "path": "cypress/tsconfig.json",
    "chars": 475,
    "preview": "{\n  \"compilerOptions\": {\n    \"target\": \"es5\",\n    \"lib\": [\"es2015\", \"dom\", \"esnext\"],\n    \"types\": [\"cypress\"],\n    \"iso"
  },
  {
    "path": "cypress.json",
    "chars": 91,
    "preview": "{\n  \"baseUrl\": \"http://localhost:8881\",\n  \"defaultCommandTimeout\": 8000,\n  \"video\": false\n}"
  },
  {
    "path": "docs/README.md",
    "chars": 73,
    "preview": "# 文档\n\n- [开发文档](./dev.md)\n- [发布到 npm](./publish.md)\n- [加入研发团队](./join.md)\n"
  },
  {
    "path": "docs/dev.md",
    "chars": 626,
    "preview": "# 开发\n\n## 准备工作\n\n- 了解 slate.js\n- 了解 vdom 和 snabbdom.js\n- 了解 lerna\n- 已安装 yarn\n\n## 本地启动\n\n### 打包\n\n- 下载代码到本地,进入 `wangEditor` 目"
  },
  {
    "path": "docs/join.md",
    "chars": 600,
    "preview": "# 加入团队\n\n欢迎加入 wangEditor 研发团队~\n\n## V5 研发人员\n\n- [王福朋](https://github.com/wangfupeng1988/) - wangEditor 创始人,资深前端工程师,PMP,曾就职于"
  },
  {
    "path": "docs/publish.md",
    "chars": 1005,
    "preview": "# 发布到 NPM\n\n因为我们的项目是使用 `independent` 的方式组织 `muti-packgae`,所以每个包都有单独的版本号,默认使用 `lerna publish` 发布包,我们需要根据包的修改内容选择合适的版本号。**对"
  },
  {
    "path": "docs/test.md",
    "chars": 1183,
    "preview": "# 测试\n目前我们的项目已经集成了基于 `Jest` 的单元测试和基于 `Cypress` 的 `E2E` 测试,下面简单介绍两种测试运行和编写的方式。\n\n## 单元测试\n单元测试是从最底层 `API` 的角度出发,保证编辑功能的质量。虽然"
  },
  {
    "path": "jest.config.js",
    "chars": 799,
    "preview": "module.exports = {\n  roots: ['<rootDir>/packages'],\n  testEnvironment: 'jsdom',\n  testMatch: ['**/(*.)+(spec|test).+(ts|"
  },
  {
    "path": "lerna.json",
    "chars": 874,
    "preview": "{\n  \"packages\": [\n    \"packages/*\"\n  ],\n  \"version\": \"independent\",\n  \"npmClient\": \"yarn\",\n  \"useWorkspaces\": true,\n  \"c"
  },
  {
    "path": "package.json",
    "chars": 3876,
    "preview": "{\n  \"name\": \"@wangeditor-team/wangeditor\",\n  \"private\": true,\n  \"scripts\": {\n    \"test\": \"cross-env NODE_OPTIONS=--unhan"
  },
  {
    "path": "packages/basic-modules/CHANGELOG.md",
    "chars": 13468,
    "preview": "# Change Log\n\nAll notable changes to this project will be documented in this file.\nSee [Conventional Commits](https://co"
  },
  {
    "path": "packages/basic-modules/README.md",
    "chars": 105,
    "preview": "# wangEditor basic-modules\n\nBasic modules built in [wangEditor](https://www.wangeditor.com/) by default.\n"
  },
  {
    "path": "packages/basic-modules/__tests__/blockquote/blockquote-menu.test.ts",
    "chars": 1381,
    "preview": "/**\n * @description blockquote menu test\n * @author wangfupeng\n */\n\nimport { Editor, Transforms } from 'slate'\nimport cr"
  },
  {
    "path": "packages/basic-modules/__tests__/blockquote/elem-to-html.test.ts",
    "chars": 464,
    "preview": "/**\n * @description blockquote - elem to html test\n * @author wangfupeng\n */\n\nimport { quoteToHtmlConf } from '../../src"
  },
  {
    "path": "packages/basic-modules/__tests__/blockquote/parse-html.test.ts",
    "chars": 1739,
    "preview": "/**\n * @description parse html test\n * @author wangfupeng\n */\n\nimport { $ } from 'dom7'\nimport { BaseElement } from 'sla"
  },
  {
    "path": "packages/basic-modules/__tests__/blockquote/plugin.test.ts",
    "chars": 1257,
    "preview": "/**\n * @description blockquote plugin test\n * @author wangfupeng\n */\n\nimport { Editor, Transforms } from 'slate'\nimport "
  },
  {
    "path": "packages/basic-modules/__tests__/blockquote/render-elem.test.ts",
    "chars": 569,
    "preview": "/**\n * @description blockquote render elem test\n * @author wangfupeng\n */\n\nimport createEditor from '../../../../tests/u"
  },
  {
    "path": "packages/basic-modules/__tests__/code-block/code-block-menu.test.ts",
    "chars": 2382,
    "preview": "/**\n * @description code-block menu test\n * @author wangfupeng\n */\n\nimport { Editor, Transforms, Element } from 'slate'\n"
  },
  {
    "path": "packages/basic-modules/__tests__/code-block/elem-to-html.test.ts",
    "chars": 668,
    "preview": "/**\n * @description code-block elem to html test\n * @author wangfupeng\n */\n\nimport { codeToHtmlConf, preToHtmlConf } fro"
  },
  {
    "path": "packages/basic-modules/__tests__/code-block/parse-html.test.ts",
    "chars": 1859,
    "preview": "/**\n * @description parse elem html\n * @author wangfupeng\n */\n\nimport { $ } from 'dom7'\nimport createEditor from '../../"
  },
  {
    "path": "packages/basic-modules/__tests__/code-block/plugin.test.ts",
    "chars": 2422,
    "preview": "/**\n * @description code-block plugin test\n * @author wangfupeng\n */\n\nimport { Editor, Transforms } from 'slate'\nimport "
  },
  {
    "path": "packages/basic-modules/__tests__/code-block/render-elem.test.ts",
    "chars": 766,
    "preview": "/**\n * @description code-block render elem test\n * @author wangfupeng\n */\n\nimport createEditor from '../../../../tests/u"
  },
  {
    "path": "packages/basic-modules/__tests__/color/color-menus.test.ts",
    "chars": 1841,
    "preview": "/**\n * @description color menus test\n * @author wangfupeng\n */\n\nimport { Editor, Transforms } from 'slate'\nimport create"
  },
  {
    "path": "packages/basic-modules/__tests__/color/parse-html.test.ts",
    "chars": 1191,
    "preview": "/**\n * @description parse html test\n * @author wangfupeng\n */\n\nimport { $ } from 'dom7'\nimport createEditor from '../../"
  },
  {
    "path": "packages/basic-modules/__tests__/color/render-text-style.test.tsx",
    "chars": 661,
    "preview": "/**\n * @description color - render text style test\n * @author wangfupeng\n */\n\nimport { jsx } from 'snabbdom'\nimport { re"
  },
  {
    "path": "packages/basic-modules/__tests__/color/text-style-to-html.test.ts",
    "chars": 521,
    "preview": "/**\n * @description color - text style to html test\n * @author wangfupeng\n */\n\nimport { styleToHtml } from '../../src/mo"
  },
  {
    "path": "packages/basic-modules/__tests__/divider/elem-to-html.test.ts",
    "chars": 436,
    "preview": "/**\n * @description divider - elem to html test\n * @author wangfupeng\n */\n\nimport { dividerToHtmlConf } from '../../src/"
  },
  {
    "path": "packages/basic-modules/__tests__/divider/insert-divider-menu.test.ts",
    "chars": 1175,
    "preview": "/**\n * @description insert divider menu test\n * @author wangfupeng\n */\n\nimport { Editor } from 'slate'\nimport createEdit"
  },
  {
    "path": "packages/basic-modules/__tests__/divider/parse-html.test.ts",
    "chars": 640,
    "preview": "/**\n * @description parse html test\n * @author wangfupeng\n */\n\nimport { $ } from 'dom7'\nimport createEditor from '../../"
  },
  {
    "path": "packages/basic-modules/__tests__/divider/plugin.test.ts",
    "chars": 1124,
    "preview": "/**\n * @description divider plugin test\n * @author wangfupeng\n */\n\nimport { Editor } from 'slate'\nimport createEditor fr"
  },
  {
    "path": "packages/basic-modules/__tests__/divider/render-elem.test.ts",
    "chars": 1104,
    "preview": "/**\n * @description divider - render elem test\n * @author wangfupeng\n */\n\nimport { Editor } from 'slate'\nimport createEd"
  },
  {
    "path": "packages/basic-modules/__tests__/emotion/emotion-menu.test.ts",
    "chars": 1053,
    "preview": "/**\n * @description emotion menu test\n * @author wangfupeng\n */\n\nimport { Editor, Transforms } from 'slate'\nimport creat"
  },
  {
    "path": "packages/basic-modules/__tests__/font-size-family/menu/font-family-menu.test.ts",
    "chars": 1780,
    "preview": "/**\n * @description font family menu test\n * @author wangfupeng\n */\n\nimport { Editor, Transforms } from 'slate'\nimport c"
  },
  {
    "path": "packages/basic-modules/__tests__/font-size-family/menu/font-size-menu.test.ts",
    "chars": 1768,
    "preview": "/**\n * @description font size menu test\n * @author wangfupeng\n */\n\nimport { Editor, Transforms } from 'slate'\nimport cre"
  },
  {
    "path": "packages/basic-modules/__tests__/font-size-family/parse-html.test.ts",
    "chars": 1169,
    "preview": "/**\n * @description parse html test\n * @author wangfupeng\n */\n\nimport { $ } from 'dom7'\nimport createEditor from '../../"
  },
  {
    "path": "packages/basic-modules/__tests__/font-size-family/render-text-style.test.tsx",
    "chars": 666,
    "preview": "/**\n * @description font size and family - render text style test\n * @author wangfupeng\n */\n\nimport { jsx } from 'snabbd"
  },
  {
    "path": "packages/basic-modules/__tests__/font-size-family/text-style-to-html.test.ts",
    "chars": 569,
    "preview": "/**\n * @description font size and family - text style to html test\n * @author wangfupeng\n */\n\nimport { styleToHtml } fro"
  },
  {
    "path": "packages/basic-modules/__tests__/full-screen/full-screen-menu.test.ts",
    "chars": 568,
    "preview": "/**\n * @description full screen menu test\n * @author wangfupeng\n */\n\nimport createEditor from '../../../../tests/utils/c"
  },
  {
    "path": "packages/basic-modules/__tests__/header/elem-to-html.test.ts",
    "chars": 1291,
    "preview": "/**\n * @description header - elem to html test\n * @author wangfupeng\n */\n\nimport {\n  header1ToHtmlConf,\n  header2ToHtmlC"
  },
  {
    "path": "packages/basic-modules/__tests__/header/helper.test.ts",
    "chars": 1407,
    "preview": "/**\n * @description header helper test\n * @author wangfupeng\n */\n\nimport { Editor, Transforms } from 'slate'\nimport crea"
  },
  {
    "path": "packages/basic-modules/__tests__/header/menu/header-select-menu.test.ts",
    "chars": 986,
    "preview": "/**\n * @description header select menu test\n * @author wangfupeng\n */\n\nimport { Editor, Transforms } from 'slate'\nimport"
  },
  {
    "path": "packages/basic-modules/__tests__/header/menu/header1-menu.test.ts",
    "chars": 3231,
    "preview": "/**\n * @description header1 menu test\n * @author wangfupeng\n */\n\nimport { Editor } from 'slate'\nimport createEditor from"
  },
  {
    "path": "packages/basic-modules/__tests__/header/parse-html.test.ts",
    "chars": 1128,
    "preview": "/**\n * @description parse html test\n * @author wangfupeng\n */\n\nimport { $ } from 'dom7'\nimport createEditor from '../../"
  },
  {
    "path": "packages/basic-modules/__tests__/header/plugin.test.ts",
    "chars": 633,
    "preview": "/**\n * @description header plugin test\n * @author wangfupeng\n */\n\nimport { Editor, Transforms } from 'slate'\nimport crea"
  },
  {
    "path": "packages/basic-modules/__tests__/header/render-elem.test.ts",
    "chars": 1548,
    "preview": "/**\n * @description header - render elem test\n * @author wangfupeng\n */\n\nimport createEditor from '../../../../tests/uti"
  },
  {
    "path": "packages/basic-modules/__tests__/image/elem-to-html.test.ts",
    "chars": 730,
    "preview": "/**\n * @description image - elem to html test\n * @author wangfupeng\n */\n\nimport { imageToHtmlConf } from '../../src/modu"
  },
  {
    "path": "packages/basic-modules/__tests__/image/helper.test.ts",
    "chars": 2083,
    "preview": "/**\n * @description image helper test\n * @author wangfupeng\n */\n\nimport { Editor, Transforms } from 'slate'\nimport { Dom"
  },
  {
    "path": "packages/basic-modules/__tests__/image/menu/del-image.test.ts",
    "chars": 1595,
    "preview": "/**\n * @description delete image menu test\n * @author wangfupeng\n */\n\nimport { Editor } from 'slate'\nimport createEditor"
  },
  {
    "path": "packages/basic-modules/__tests__/image/menu/edit-image.test.ts",
    "chars": 2252,
    "preview": "/**\n * @description edit image menu test\n * @author wangfupeng\n */\n\nimport { Editor } from 'slate'\nimport createEditor f"
  },
  {
    "path": "packages/basic-modules/__tests__/image/menu/insert-image.test.ts",
    "chars": 1371,
    "preview": "/**\n * @description insert image menu test\n * @author wangfupeng\n */\n\nimport { Editor, Transforms } from 'slate'\nimport "
  },
  {
    "path": "packages/basic-modules/__tests__/image/menu/view-image-link.test.ts",
    "chars": 1266,
    "preview": "/**\n * @description view image link menu test\n * @author wangfupeng\n */\n\nimport { Editor } from 'slate'\nimport createEdi"
  },
  {
    "path": "packages/basic-modules/__tests__/image/menu/width-menus.test.ts",
    "chars": 2655,
    "preview": "/**\n * @description image width menus test\n * @author wangfupeng\n */\n\nimport { Editor } from 'slate'\nimport createEditor"
  },
  {
    "path": "packages/basic-modules/__tests__/image/parse-html.test.ts",
    "chars": 866,
    "preview": "/**\n * @description parse html test\n * @author wangfupeng\n */\n\nimport { $ } from 'dom7'\nimport createEditor from '../../"
  },
  {
    "path": "packages/basic-modules/__tests__/image/plugin.test.ts",
    "chars": 490,
    "preview": "/**\n * @description image plugin test\n * @author wangfupeng\n */\n\nimport createEditor from '../../../../tests/utils/creat"
  },
  {
    "path": "packages/basic-modules/__tests__/image/render-elem.test.ts",
    "chars": 2219,
    "preview": "/**\n * @description image - render elem test\n * @author wangfupeng\n */\n\nimport { Editor } from 'slate'\nimport { renderIm"
  },
  {
    "path": "packages/basic-modules/__tests__/indent/menu/decrease-indent-menu.test.ts",
    "chars": 1451,
    "preview": "/**\n * @description decrease indent menu test\n * @author wangfupeng\n */\n\nimport { Editor, Transforms } from 'slate'\nimpo"
  },
  {
    "path": "packages/basic-modules/__tests__/indent/menu/increase-indent-menu.test.ts",
    "chars": 1494,
    "preview": "/**\n * @description increase indent menu test\n * @author wangfupeng\n */\n\nimport { Editor, Transforms } from 'slate'\nimpo"
  },
  {
    "path": "packages/basic-modules/__tests__/indent/parse-html.test.ts",
    "chars": 1369,
    "preview": "/**\n * @description parse html test\n * @author wangfupeng\n */\n\nimport { $ } from 'dom7'\nimport createEditor from '../../"
  },
  {
    "path": "packages/basic-modules/__tests__/indent/render-text-style.test.tsx",
    "chars": 519,
    "preview": "/**\n * @description indent - render text style\n * @author wangfupeng\n */\n\nimport { jsx } from 'snabbdom'\nimport { render"
  },
  {
    "path": "packages/basic-modules/__tests__/indent/text-style-to-html.test.ts",
    "chars": 448,
    "preview": "/**\n * @description indent - text style to html test\n * @author wangfupeng\n */\n\nimport { styleToHtml } from '../../src/m"
  },
  {
    "path": "packages/basic-modules/__tests__/justify/menus.test.ts",
    "chars": 1963,
    "preview": "/**\n * @description justify menus test\n * @author wangfupeng\n */\n\nimport { Editor, Transforms } from 'slate'\nimport crea"
  },
  {
    "path": "packages/basic-modules/__tests__/justify/parse-html.test.ts",
    "chars": 668,
    "preview": "/**\n * @description parse html test\n * @author wangfupeng\n */\n\nimport { $ } from 'dom7'\nimport createEditor from '../../"
  },
  {
    "path": "packages/basic-modules/__tests__/justify/render-text-style.test.tsx",
    "chars": 546,
    "preview": "/**\n * @description justify - render text style test\n * @author wangfupeng\n */\n\nimport { jsx } from 'snabbdom'\nimport { "
  },
  {
    "path": "packages/basic-modules/__tests__/justify/text-style-to-html.test.ts",
    "chars": 445,
    "preview": "/**\n * @description justify - text style to html test\n * @author wangfupeng\n */\n\nimport { styleToHtml } from '../../src/"
  },
  {
    "path": "packages/basic-modules/__tests__/line-height/line-height-menu.test.ts",
    "chars": 1975,
    "preview": "/**\n * @description line-height menu test\n * @author wangfupeng\n */\n\nimport { Editor, Transforms } from 'slate'\nimport c"
  },
  {
    "path": "packages/basic-modules/__tests__/line-height/parse-html.test.ts",
    "chars": 669,
    "preview": "/**\n * @description parse html test\n * @author wangfupeng\n */\n\nimport { $ } from 'dom7'\nimport createEditor from '../../"
  },
  {
    "path": "packages/basic-modules/__tests__/line-height/render-text-style.test.tsx",
    "chars": 553,
    "preview": "/**\n * @description line-height render text style test\n * @author wangfupeng\n */\n\nimport { jsx } from 'snabbdom'\nimport "
  },
  {
    "path": "packages/basic-modules/__tests__/line-height/text-style-to-html.test.ts",
    "chars": 451,
    "preview": "/**\n * @description line-height text-style-to-html test\n * @author wangfupeng\n */\n\nimport { styleToHtml } from '../../sr"
  },
  {
    "path": "packages/basic-modules/__tests__/link/elem-to-html.test.ts",
    "chars": 528,
    "preview": "/**\n * @description link - elem to html test\n * @author wangfupeng\n */\n\nimport { linkToHtmlConf } from '../../src/module"
  },
  {
    "path": "packages/basic-modules/__tests__/link/helper.test.ts",
    "chars": 2496,
    "preview": "/**\n * @description link module helper test\n * @author wangfupeng\n */\n\nimport { Editor, Transforms } from 'slate'\nimport"
  },
  {
    "path": "packages/basic-modules/__tests__/link/menu/edit-link-menu.test.ts",
    "chars": 1814,
    "preview": "/**\n * @description edit link menu test\n * @author wangfupeng\n */\n\nimport { Editor } from 'slate'\nimport createEditor fr"
  },
  {
    "path": "packages/basic-modules/__tests__/link/menu/insert-link-menu.test.ts",
    "chars": 999,
    "preview": "/**\n * @description insert link menu test\n * @author wangfupeng\n */\n\nimport { Editor } from 'slate'\nimport createEditor "
  },
  {
    "path": "packages/basic-modules/__tests__/link/menu/unlink-menu.test.ts",
    "chars": 1343,
    "preview": "/**\n * @description unlink menu test\n * @author wangfupeng\n */\n\nimport { Editor } from 'slate'\nimport createEditor from "
  },
  {
    "path": "packages/basic-modules/__tests__/link/menu/view-link-menu.test.ts",
    "chars": 1263,
    "preview": "/**\n * @description view link menu test\n * @author wangfupeng\n */\n\nimport { Editor } from 'slate'\nimport createEditor fr"
  },
  {
    "path": "packages/basic-modules/__tests__/link/parse-html.test.ts",
    "chars": 1275,
    "preview": "/**\n * @description parse html test\n * @author wangfupeng\n */\n\nimport { $ } from 'dom7'\nimport createEditor from '../../"
  },
  {
    "path": "packages/basic-modules/__tests__/link/plugin.test.ts",
    "chars": 1147,
    "preview": "/**\n * @description link plugin test\n * @author wangfupeng\n */\n\nimport { Editor } from 'slate'\nimport withLink from '../"
  },
  {
    "path": "packages/basic-modules/__tests__/link/render-elem.test.ts",
    "chars": 677,
    "preview": "/**\n * @description link - render elem test\n * @author wangfupeng\n */\n\nimport createEditor from '../../../../tests/utils"
  },
  {
    "path": "packages/basic-modules/__tests__/paragraph/elem-to-html.test.ts",
    "chars": 706,
    "preview": "import { html } from 'dom7'\n/**\n * @description paragraph - elem to html test\n * @author wangfupeng\n */\n\nimport { pToHtm"
  },
  {
    "path": "packages/basic-modules/__tests__/paragraph/parse-html.test.ts",
    "chars": 1053,
    "preview": "/**\n * @description parse html test\n * @author wangfupeng\n */\n\nimport { $ } from 'dom7'\nimport createEditor from '../../"
  },
  {
    "path": "packages/basic-modules/__tests__/paragraph/plugin.test.ts",
    "chars": 1134,
    "preview": "/**\n * @description paragraph plugin test\n * @author wangfupeng\n */\n\nimport { Editor, Transforms, Point } from 'slate'\ni"
  },
  {
    "path": "packages/basic-modules/__tests__/paragraph/render-elem.test.ts",
    "chars": 546,
    "preview": "/**\n * @description paragraph render elem test\n * @author wangfupeng\n */\n\nimport createEditor from '../../../../tests/ut"
  },
  {
    "path": "packages/basic-modules/__tests__/text-style/menu/clear-style-menu.test.ts",
    "chars": 827,
    "preview": "/**\n * @description clear style menu test\n * @author wangfupeng\n */\n\nimport { Editor } from 'slate'\nimport createEditor "
  },
  {
    "path": "packages/basic-modules/__tests__/text-style/menu/menus.test.ts",
    "chars": 2661,
    "preview": "/**\n * @description style menus test\n * @author wangfupeng\n */\n\nimport { Editor, Transforms, Element } from 'slate'\nimpo"
  },
  {
    "path": "packages/basic-modules/__tests__/text-style/parse-html.test.ts",
    "chars": 676,
    "preview": "/**\n * @description parse html test\n * @author wangfupeng\n */\n\n// import { $ } from 'dom7'\n// import { parseStyleHtml } "
  },
  {
    "path": "packages/basic-modules/__tests__/text-style/parse-style-html.test.ts",
    "chars": 3089,
    "preview": "import { parseStyleHtml } from '../../src/modules/text-style/parse-style-html'\nimport $ from '../../src/utils/dom'\nimpor"
  },
  {
    "path": "packages/basic-modules/__tests__/text-style/text-style.test.tsx",
    "chars": 1398,
    "preview": "/**\n * @description text style test\n * @author wangfupeng\n */\n\nimport { jsx } from 'snabbdom'\nimport { renderStyle } fro"
  },
  {
    "path": "packages/basic-modules/__tests__/text-style/text-to-html.test.ts",
    "chars": 765,
    "preview": "/**\n * @description text to html test\n * @author wangfupeng\n */\n\nimport { styleToHtml } from '../../src/modules/text-sty"
  },
  {
    "path": "packages/basic-modules/__tests__/todo/elem-to-html.test.ts",
    "chars": 817,
    "preview": "/**\n * @description todo elem to html test\n * @author wangfupeng\n */\n\nimport { todoToHtmlConf } from '../../src/modules/"
  },
  {
    "path": "packages/basic-modules/__tests__/todo/menu/todo-menu.test.ts",
    "chars": 2506,
    "preview": "/**\n * @description todo-menu test\n * @author wangfupeng\n */\n\nimport { Editor, Transforms } from 'slate'\nimport createEd"
  },
  {
    "path": "packages/basic-modules/__tests__/todo/parse-html.test.ts",
    "chars": 1259,
    "preview": "/**\n * @description todo parse html test\n * @author wangfupeng\n */\n\nimport { $ } from 'dom7'\nimport createEditor from '."
  },
  {
    "path": "packages/basic-modules/__tests__/todo/plugin.test.ts",
    "chars": 673,
    "preview": "/**\n * @description todo plugin test\n * @author wangfupeng\n */\n\nimport withTodo from '../../src/modules/todo/plugin'\nimp"
  },
  {
    "path": "packages/basic-modules/__tests__/todo/pre-parse-html.test.ts",
    "chars": 696,
    "preview": "/**\n * @description todo pre-parse html\n * @author wangfupeng\n */\n\nimport { $ } from 'dom7'\nimport { preParseHtmlConf } "
  },
  {
    "path": "packages/basic-modules/__tests__/todo/render-elem.test.ts",
    "chars": 942,
    "preview": "/**\n * @description todo render elem\n * @author wangfupeng\n */\n\nimport createEditor from '../../../../tests/utils/create"
  },
  {
    "path": "packages/basic-modules/__tests__/undo-redo/redo-menu.test.ts",
    "chars": 1082,
    "preview": "/**\n * @description redo menu test\n * @author wangfupeng\n */\n\nimport { Editor } from 'slate'\nimport createEditor from '."
  },
  {
    "path": "packages/basic-modules/__tests__/undo-redo/undo-menu.test.ts",
    "chars": 1003,
    "preview": "/**\n * @description undo menu test\n * @author wangfupeng\n */\n\nimport { Editor } from 'slate'\nimport createEditor from '."
  },
  {
    "path": "packages/basic-modules/package.json",
    "chars": 1655,
    "preview": "{\n  \"name\": \"@wangeditor/basic-modules\",\n  \"version\": \"1.1.7\",\n  \"description\": \"wangEditor basic modules\",\n  \"author\": "
  },
  {
    "path": "packages/basic-modules/rollup.config.js",
    "chars": 480,
    "preview": "import { createRollupConfig, IS_PRD } from '../../build/create-rollup-config'\nimport pkg from './package.json'\n\nconst na"
  },
  {
    "path": "packages/basic-modules/src/assets/blockquote.less",
    "chars": 288,
    "preview": "@import \"../../../vars.less\";\n\n.w-e-text-container [data-slate-editor] blockquote {\n  display: block;\n  border-left: 8px"
  },
  {
    "path": "packages/basic-modules/src/assets/code-block.less",
    "chars": 281,
    "preview": "@import \"../../../vars.less\";\n\n.w-e-text-container [data-slate-editor] pre>code {\n  display: block;\n  border: 1px solid "
  },
  {
    "path": "packages/basic-modules/src/assets/color.less",
    "chars": 674,
    "preview": "@import \"../../../vars.less\";\n\n.w-e-panel-content-color {\n  list-style: none;\n  text-align: left;\n  width: 230px;\n\n  li "
  },
  {
    "path": "packages/basic-modules/src/assets/divider.less",
    "chars": 307,
    "preview": "@import \"../../../vars.less\";\n\n.w-e-textarea-divider {\n  padding: 20px 20px;\n  margin: 20px auto;\n  border-radius: 3px;\n"
  },
  {
    "path": "packages/basic-modules/src/assets/emotion.less",
    "chars": 316,
    "preview": "@import \"../../../vars.less\";\n\n.w-e-panel-content-emotion {\n  list-style: none;\n  text-align: left;\n  width: 300px;\n  fo"
  },
  {
    "path": "packages/basic-modules/src/assets/image.less",
    "chars": 1056,
    "preview": "@import \"../../../vars.less\";\n\n// 拖拽,修改图片尺寸\n.w-e-text-container [data-slate-editor] {\n  .w-e-image-container {\n    displ"
  },
  {
    "path": "packages/basic-modules/src/assets/index.less",
    "chars": 202,
    "preview": "@import \"simple-style.less\";\n@import \"color.less\";\n@import \"blockquote.less\";\n@import \"emotion.less\";\n@import \"divider.l"
  },
  {
    "path": "packages/basic-modules/src/assets/simple-style.less",
    "chars": 191,
    "preview": "@import \"../../../vars.less\";\n\n.w-e-text-container [data-slate-editor] code {\n  font-family: monospace;\n  background-col"
  },
  {
    "path": "packages/basic-modules/src/constants/icon-svg.ts",
    "chars": 18501,
    "preview": "/**\n * @description icon svg\n * @author wangfupeng\n */\n\n/**\n * 【注意】svg 字符串的长度 ,否则会导致代码体积过大\n * 尽量选择 https://www.iconfont."
  },
  {
    "path": "packages/basic-modules/src/index.ts",
    "chars": 1897,
    "preview": "/**\n * @description basic index\n * @author wangfupeng\n */\n\nimport './assets/index.less'\n\n// 配置多语言\nimport './locale/index"
  },
  {
    "path": "packages/basic-modules/src/locale/en.ts",
    "chars": 1566,
    "preview": "/**\n * @description i18n en\n * @author wangfupeng\n */\n\nexport default {\n  // 通用的词\n  common: {\n    ok: 'OK',\n    delete: "
  },
  {
    "path": "packages/basic-modules/src/locale/index.ts",
    "chars": 251,
    "preview": "/**\n * @description i18n entry\n * @author wangfupeng\n */\n\nimport { i18nAddResources } from '@wangeditor/core'\nimport enR"
  },
  {
    "path": "packages/basic-modules/src/locale/zh-CN.ts",
    "chars": 1333,
    "preview": "/**\n * @description i18n zh-CN\n * @author wangfupeng\n */\n\nexport default {\n  // 通用的词\n  common: {\n    ok: '确定',\n    delet"
  },
  {
    "path": "packages/basic-modules/src/modules/blockquote/custom-types.ts",
    "chars": 214,
    "preview": "/**\n * @description 自定义 element\n * @author wangfupeng\n */\n\nimport { Text } from 'slate'\n\n//【注意】需要把自定义的 Element 引入到最外层的 c"
  },
  {
    "path": "packages/basic-modules/src/modules/blockquote/elem-to-html.ts",
    "chars": 295,
    "preview": "/**\n * @description to html\n * @author wangfupeng\n */\n\nimport { Element } from 'slate'\n\nfunction quoteToHtml(elem: Eleme"
  },
  {
    "path": "packages/basic-modules/src/modules/blockquote/index.ts",
    "chars": 595,
    "preview": "/**\n * @description blockquote entry\n * @author wangfupeng\n */\n\nimport { IModuleConf } from '@wangeditor/core'\nimport { "
  },
  {
    "path": "packages/basic-modules/src/modules/blockquote/menu/BlockquoteMenu.ts",
    "chars": 1539,
    "preview": "/**\n * @description blockquote menu class\n * @author wangfupeng\n */\n\nimport { Editor, Transforms } from 'slate'\nimport {"
  },
  {
    "path": "packages/basic-modules/src/modules/blockquote/menu/index.ts",
    "chars": 221,
    "preview": "/**\n * @description block quote menu\n * @author wangfupeng\n */\n\nimport BlockquoteMenu from './BlockquoteMenu'\n\nexport co"
  },
  {
    "path": "packages/basic-modules/src/modules/blockquote/parse-elem-html.ts",
    "chars": 864,
    "preview": "/**\n * @description parse html\n * @author wangfupeng\n */\n\nimport { Descendant, Text } from 'slate'\nimport $, { DOMElemen"
  },
  {
    "path": "packages/basic-modules/src/modules/blockquote/plugin.ts",
    "chars": 1369,
    "preview": "/**\n * @description editor 插件,重写 editor API\n * @author wangfupeng\n */\n\nimport { Editor, Transforms, Node, Point } from '"
  },
  {
    "path": "packages/basic-modules/src/modules/blockquote/render-elem.tsx",
    "chars": 604,
    "preview": "/**\n * @description render elem\n * @author wangfupeng\n */\n\nimport { Element as SlateElement } from 'slate'\nimport { jsx,"
  },
  {
    "path": "packages/basic-modules/src/modules/code-block/custom-types.ts",
    "chars": 301,
    "preview": "/**\n * @description 自定义 element\n * @author wangfupeng\n */\n\n//【注意】需要把自定义的 Element 引入到最外层的 custom-types.d.ts\n\ntype PureTex"
  },
  {
    "path": "packages/basic-modules/src/modules/code-block/elem-to-html.ts",
    "chars": 509,
    "preview": "/**\n * @description to html\n * @author wangfupeng\n */\n\nimport { Element } from 'slate'\n\nfunction codeToHtml(elem: Elemen"
  },
  {
    "path": "packages/basic-modules/src/modules/code-block/index.ts",
    "chars": 780,
    "preview": "/**\n * @description code block module\n * @author wangfupeng\n */\n\nimport { IModuleConf } from '@wangeditor/core'\nimport {"
  },
  {
    "path": "packages/basic-modules/src/modules/code-block/menu/CodeBlockMenu.ts",
    "chars": 3307,
    "preview": "/**\n * @description insert code-block menu\n * @author wangfupeng\n */\n\nimport { Editor, Element, Transforms, Node, Range "
  },
  {
    "path": "packages/basic-modules/src/modules/code-block/menu/index.ts",
    "chars": 215,
    "preview": "/**\n * @description code-block menu\n * @author wangfupeng\n */\n\nimport CodeBlockMenu from './CodeBlockMenu'\n\nexport const"
  },
  {
    "path": "packages/basic-modules/src/modules/code-block/parse-elem-html.ts",
    "chars": 1270,
    "preview": "/**\n * @description parse html\n * @author wangfupeng\n */\n\nimport { Descendant } from 'slate'\nimport $, { DOMElement } fr"
  },
  {
    "path": "packages/basic-modules/src/modules/code-block/plugin.ts",
    "chars": 2811,
    "preview": "/**\n * @description editor 插件,重写 editor API\n * @author wangfupeng\n */\n\nimport { Editor, Transforms, Node as SlateNode, E"
  },
  {
    "path": "packages/basic-modules/src/modules/code-block/pre-parse-html.ts",
    "chars": 681,
    "preview": "/**\n * @description pre parse html\n * @author wangfupeng\n */\n\nimport $, { DOMElement } from '../../utils/dom'\nimport { g"
  },
  {
    "path": "packages/basic-modules/src/modules/code-block/render-elem.tsx",
    "chars": 731,
    "preview": "/**\n * @description render elem\n * @author wangfupeng\n */\n\nimport { Element as SlateElement } from 'slate'\nimport { jsx,"
  },
  {
    "path": "packages/basic-modules/src/modules/color/custom-types.ts",
    "chars": 184,
    "preview": "/**\n * @description 自定义 element\n * @author wangfupeng\n */\n\n//【注意】需要把自定义的 Text 引入到最外层的 custom-types.d.ts\n\nexport type Col"
  },
  {
    "path": "packages/basic-modules/src/modules/color/index.ts",
    "chars": 555,
    "preview": "/**\n * @description color bgColor\n * @author wangfupeng\n */\n\nimport { IModuleConf } from '@wangeditor/core'\nimport { ren"
  },
  {
    "path": "packages/basic-modules/src/modules/color/menu/BaseMenu.ts",
    "chars": 3236,
    "preview": "/**\n * @description color base menu\n * @author wangfupeng\n */\n\nimport { Editor, Range } from 'slate'\nimport { IDropPanel"
  },
  {
    "path": "packages/basic-modules/src/modules/color/menu/BgColorMenu.ts",
    "chars": 359,
    "preview": "/**\n * @description bg color menu\n * @author wangfupeng\n */\n\nimport { t } from '@wangeditor/core'\nimport BaseMenu from '"
  },
  {
    "path": "packages/basic-modules/src/modules/color/menu/ColorMenu.ts",
    "chars": 352,
    "preview": "/**\n * @description color menu\n * @author wangfupeng\n */\n\nimport { t } from '@wangeditor/core'\nimport BaseMenu from './B"
  },
  {
    "path": "packages/basic-modules/src/modules/color/menu/config.ts",
    "chars": 1811,
    "preview": "/**\n * @description menu config\n * @author wangfupeng\n */\n\nconst COLORS = [\n  'rgb(0, 0, 0)',\n  'rgb(38, 38, 38)',\n  'rg"
  },
  {
    "path": "packages/basic-modules/src/modules/color/menu/index.ts",
    "chars": 575,
    "preview": "/**\n * @description menu entry\n * @author wangfupeng\n */\n\nimport ColorMenu from './ColorMenu'\nimport BgColorMenu from '."
  },
  {
    "path": "packages/basic-modules/src/modules/color/parse-style-html.ts",
    "chars": 756,
    "preview": "/**\n * @description parse style html\n * @author wangfupeng\n */\n\nimport { Descendant, Text } from 'slate'\nimport { IDomEd"
  },
  {
    "path": "packages/basic-modules/src/modules/color/pre-parse-html.ts",
    "chars": 624,
    "preview": "/**\n * @description pre-parse html\n * @author wangfupeng\n */\n\nimport $, { DOMElement, getTagName } from '../../utils/dom"
  },
  {
    "path": "packages/basic-modules/src/modules/color/render-style.tsx",
    "chars": 626,
    "preview": "/**\n * @description render color style\n * @author wangfupeng\n */\n\nimport { Descendant } from 'slate'\nimport { jsx, VNode"
  },
  {
    "path": "packages/basic-modules/src/modules/color/style-to-html.ts",
    "chars": 1046,
    "preview": "/**\n * @description textStyle to html\n * @author wangfupeng\n */\n\nimport { Text, Descendant } from 'slate'\nimport $, { ge"
  },
  {
    "path": "packages/basic-modules/src/modules/common/index.ts",
    "chars": 255,
    "preview": "/**\n * @description common module\n * @author wangfupeng\n */\nimport { IModuleConf } from '@wangeditor/core'\nimport { ente"
  },
  {
    "path": "packages/basic-modules/src/modules/common/menu/EnterMenu.ts",
    "chars": 1104,
    "preview": "/**\n * @description enter menu\n * @author wangfupeng\n */\n\nimport { Range, Transforms, Editor } from 'slate'\nimport { IBu"
  },
  {
    "path": "packages/basic-modules/src/modules/common/menu/index.ts",
    "chars": 198,
    "preview": "/**\n * @description common menu config\n * @author wangfupeng\n */\n\nimport EnterMenu from './EnterMenu'\n\nexport const ente"
  },
  {
    "path": "packages/basic-modules/src/modules/divider/README.md",
    "chars": 5,
    "preview": "# 分割线"
  },
  {
    "path": "packages/basic-modules/src/modules/divider/custom-types.ts",
    "chars": 220,
    "preview": "/**\n * @description divider element\n * @author wangfupeng\n */\n\n//【注意】需要把自定义的 Element 引入到最外层的 custom-types.d.ts\n\ntype Emp"
  },
  {
    "path": "packages/basic-modules/src/modules/divider/elem-to-html.ts",
    "chars": 263,
    "preview": "/**\n * @description to html\n * @author wangfupeng\n */\n\nimport { Element } from 'slate'\n\nfunction dividerToHtml(elem: Ele"
  },
  {
    "path": "packages/basic-modules/src/modules/divider/index.ts",
    "chars": 581,
    "preview": "/**\n * @description divider module\n * @author wangfupeng\n */\n\nimport { IModuleConf } from '@wangeditor/core'\nimport with"
  },
  {
    "path": "packages/basic-modules/src/modules/divider/menu/DeleteDividerMenu.ts.bak",
    "chars": 1066,
    "preview": "/**\n * @description delete divider menu\n * @author wangfupeng\n */\n\nimport { Transforms } from 'slate'\nimport { IButtonMe"
  },
  {
    "path": "packages/basic-modules/src/modules/divider/menu/InsertDividerMenu.ts",
    "chars": 1375,
    "preview": "/**\n * @description insert divider menu\n * @author wangfupeng\n */\n\nimport { Transforms } from 'slate'\nimport { IButtonMe"
  },
  {
    "path": "packages/basic-modules/src/modules/divider/menu/index.ts",
    "chars": 470,
    "preview": "/**\n * @description divider menu\n * @author wangfupeng\n */\n\nimport InsertDividerMenu from './InsertDividerMenu'\n// impor"
  },
  {
    "path": "packages/basic-modules/src/modules/divider/parse-elem-html.ts",
    "chars": 562,
    "preview": "/**\n * @description parse html\n * @author wangfupeng\n */\n\nimport { Descendant } from 'slate'\nimport $, { DOMElement } fr"
  },
  {
    "path": "packages/basic-modules/src/modules/divider/plugin.ts",
    "chars": 1010,
    "preview": "/**\n * @description editor 插件,重写 editor API\n * @author wangfupeng\n */\n\nimport { Transforms, Element } from 'slate'\nimpor"
  },
  {
    "path": "packages/basic-modules/src/modules/divider/render-elem.tsx",
    "chars": 958,
    "preview": "/**\n * @description render divider elem\n * @author wangfupeng\n */\n\nimport { Element as SlateElement } from 'slate'\nimpor"
  },
  {
    "path": "packages/basic-modules/src/modules/emotion/index.ts",
    "chars": 250,
    "preview": "/**\n * @description emotion entry\n * @author wangfupeng\n */\n\nimport { IModuleConf } from '@wangeditor/core'\nimport { emo"
  },
  {
    "path": "packages/basic-modules/src/modules/emotion/menu/EmotionMenu.ts",
    "chars": 2190,
    "preview": "/**\n * @description emotion menu\n * @author wangfupeng\n */\n\nimport { Editor } from 'slate'\nimport { IDropPanelMenu, IDom"
  },
  {
    "path": "packages/basic-modules/src/modules/emotion/menu/config.ts",
    "chars": 328,
    "preview": "/**\n * @description menu config\n * @author wangfupeng\n */\n\nexport function genConfig() {\n  const emotions =\n    '😀 😃 😄 😁"
  },
  {
    "path": "packages/basic-modules/src/modules/emotion/menu/index.ts",
    "chars": 390,
    "preview": "/**\n * @description emotion menu\n * @author wangfupeng\n */\n\nimport EmotionMenu from './EmotionMenu'\nimport { genConfig }"
  },
  {
    "path": "packages/basic-modules/src/modules/font-size-family/custom-types.ts",
    "chars": 202,
    "preview": "/**\n * @description 自定义 element\n * @author wangfupeng\n */\n\n//【注意】需要把自定义的 Text 引入到最外层的 custom-types.d.ts\n\nexport type Fon"
  },
  {
    "path": "packages/basic-modules/src/modules/font-size-family/index.ts",
    "chars": 599,
    "preview": "/**\n * @description font-size font-family\n * @author wangfupeng\n */\n\nimport { IModuleConf } from '@wangeditor/core'\nimpo"
  },
  {
    "path": "packages/basic-modules/src/modules/font-size-family/menu/BaseMenu.ts",
    "chars": 1456,
    "preview": "/**\n * @description header menu\n * @author wangfupeng\n */\n\nimport { Editor } from 'slate'\nimport { ISelectMenu, IDomEdit"
  },
  {
    "path": "packages/basic-modules/src/modules/font-size-family/menu/FontFamilyMenu.ts",
    "chars": 1500,
    "preview": "/**\n * @description font-family menu\n * @author wangfupeng\n */\n\nimport { IDomEditor, IOption, t } from '@wangeditor/core"
  },
  {
    "path": "packages/basic-modules/src/modules/font-size-family/menu/FontSizeMenu.ts",
    "chars": 1320,
    "preview": "/**\n * @description font-size menu\n * @author wangfupeng\n */\n\nimport { IDomEditor, IOption, t } from '@wangeditor/core'\n"
  },
  {
    "path": "packages/basic-modules/src/modules/font-size-family/menu/config.ts",
    "chars": 886,
    "preview": "/**\n * @description font-size font-family config\n * @author wangfupeng\n */\n\nexport function genFontSizeConfig() {\n  cons"
  },
  {
    "path": "packages/basic-modules/src/modules/font-size-family/menu/index.ts",
    "chars": 673,
    "preview": "/**\n * @description font-size font-family menu entry\n * @author wangfupeng\n */\n\nimport FontSizeMenu from './FontSizeMenu"
  },
  {
    "path": "packages/basic-modules/src/modules/font-size-family/parse-style-html.ts",
    "chars": 1353,
    "preview": "/**\n * @description parse style html\n * @author wangfupeng\n */\n\nimport { Descendant, Text } from 'slate'\nimport { IDomEd"
  },
  {
    "path": "packages/basic-modules/src/modules/font-size-family/pre-parse-html.ts",
    "chars": 1010,
    "preview": "/**\n * @description pre-parse html\n * @author wangfupeng\n */\n\nimport $, { DOMElement, getTagName } from '../../utils/dom"
  },
  {
    "path": "packages/basic-modules/src/modules/font-size-family/render-style.tsx",
    "chars": 668,
    "preview": "/**\n * @description render font-size font-family style\n * @author wangfupeng\n */\n\nimport { Descendant } from 'slate'\nimp"
  }
]

// ... and 487 more files (download for full content)

About this extraction

This page contains the full source code of the wangeditor-team/wangEditor GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 687 files (1.0 MB), approximately 341.8k tokens, and a symbol index with 1055 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.

Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.

Copied to clipboard!