diff --git a/.eslintrc.json b/.eslintrc.json index 340d2fb6a6..910542b8ae 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -30,6 +30,7 @@ "excludedFiles": "*.d.ts", "plugins": ["prettier", "@typescript-eslint"], "rules": { + "@typescript-eslint/consistent-type-imports": "error", "@typescript-eslint/ban-ts-comment": "off", "@typescript-eslint/no-empty-function": "off", "@typescript-eslint/ban-types": "off", diff --git a/blots/block.ts b/blots/block.ts index ef2838fbd2..c95248a778 100644 --- a/blots/block.ts +++ b/blots/block.ts @@ -1,12 +1,11 @@ import { AttributorStore, BlockBlot, - Blot, EmbedBlot, LeafBlot, - Parent, Scope, } from 'parchment'; +import type { Blot, Parent } from 'parchment'; import Delta from 'quill-delta'; import Break from './break'; import Inline from './inline'; diff --git a/blots/cursor.ts b/blots/cursor.ts index 8b277093f5..0f0e332286 100644 --- a/blots/cursor.ts +++ b/blots/cursor.ts @@ -1,7 +1,8 @@ -import { EmbedBlot, Parent, Scope, ScrollBlot } from 'parchment'; -import Selection from '../core/selection'; +import { EmbedBlot, Scope } from 'parchment'; +import type { Parent, ScrollBlot } from 'parchment'; +import type Selection from '../core/selection'; import TextBlot from './text'; -import { EmbedContextRange } from './embed'; +import type { EmbedContextRange } from './embed'; class Cursor extends EmbedBlot { static blotName = 'cursor'; diff --git a/blots/embed.ts b/blots/embed.ts index 4eb748edd5..9404249194 100644 --- a/blots/embed.ts +++ b/blots/embed.ts @@ -1,4 +1,5 @@ -import { EmbedBlot, ScrollBlot } from 'parchment'; +import type { ScrollBlot } from 'parchment'; +import { EmbedBlot } from 'parchment'; import TextBlot from './text'; const GUARD_TEXT = '\uFEFF'; diff --git a/blots/inline.ts b/blots/inline.ts index cb8df0af40..4acf5780fc 100644 --- a/blots/inline.ts +++ b/blots/inline.ts @@ -1,4 +1,5 @@ -import { BlotConstructor, EmbedBlot, InlineBlot, Scope } from 'parchment'; +import { EmbedBlot, InlineBlot, Scope } from 'parchment'; +import type { BlotConstructor } from 'parchment'; import Break from './break'; import Text from './text'; diff --git a/blots/scroll.ts b/blots/scroll.ts index d4b82de902..4df0045794 100644 --- a/blots/scroll.ts +++ b/blots/scroll.ts @@ -1,16 +1,8 @@ -import { - Blot, - ContainerBlot, - EmbedBlot, - LeafBlot, - Parent, - ParentBlot, - Registry, - Scope, - ScrollBlot, -} from 'parchment'; +import { ContainerBlot, LeafBlot, Scope, ScrollBlot } from 'parchment'; +import type { Blot, Parent, EmbedBlot, ParentBlot, Registry } from 'parchment'; import Delta, { AttributeMap, Op } from 'quill-delta'; -import Emitter, { EmitterSource } from '../core/emitter'; +import Emitter from '../core/emitter'; +import type { EmitterSource } from '../core/emitter'; import Block, { BlockEmbed } from './block'; import Break from './break'; import Container from './container'; diff --git a/core/composition.ts b/core/composition.ts index 7ea2fd362c..ff8f16b5df 100644 --- a/core/composition.ts +++ b/core/composition.ts @@ -1,5 +1,5 @@ import Embed from '../blots/embed'; -import Scroll from '../blots/scroll'; +import type Scroll from '../blots/scroll'; import Emitter from './emitter'; class Composition { diff --git a/core/editor.ts b/core/editor.ts index d25da97814..3cfa8d3473 100644 --- a/core/editor.ts +++ b/core/editor.ts @@ -1,12 +1,13 @@ import cloneDeep from 'lodash.clonedeep'; import isEqual from 'lodash.isequal'; import merge from 'lodash.merge'; -import { LeafBlot, EmbedBlot, Scope, Blot, ParentBlot } from 'parchment'; +import { LeafBlot, EmbedBlot, Scope, ParentBlot } from 'parchment'; +import type { Blot } from 'parchment'; import Delta, { AttributeMap, Op } from 'quill-delta'; import Block, { BlockEmbed, bubbleFormats } from '../blots/block'; import Break from '../blots/break'; import CursorBlot from '../blots/cursor'; -import Scroll from '../blots/scroll'; +import type Scroll from '../blots/scroll'; import TextBlot, { escapeText } from '../blots/text'; import { Range } from './selection'; diff --git a/core/module.ts b/core/module.ts index df47954fce..f853efda16 100644 --- a/core/module.ts +++ b/core/module.ts @@ -1,4 +1,4 @@ -import Quill from './quill'; +import type Quill from './quill'; abstract class Module { static DEFAULTS = {}; diff --git a/core/quill.ts b/core/quill.ts index eb353868d7..84cdf0597e 100644 --- a/core/quill.ts +++ b/core/quill.ts @@ -1,22 +1,30 @@ import cloneDeep from 'lodash.clonedeep'; import merge from 'lodash.merge'; import * as Parchment from 'parchment'; -import Delta, { Op } from 'quill-delta'; -import Block, { BlockEmbed } from '../blots/block'; -import Scroll, { ScrollConstructor } from '../blots/scroll'; -import Clipboard from '../modules/clipboard'; -import History from '../modules/history'; -import Keyboard from '../modules/keyboard'; -import Uploader from '../modules/uploader'; +import type { Op } from 'quill-delta'; +import Delta from 'quill-delta'; +import type { BlockEmbed } from '../blots/block'; +import type Block from '../blots/block'; +import type Scroll from '../blots/scroll'; +import type { ScrollConstructor } from '../blots/scroll'; +import type Clipboard from '../modules/clipboard'; +import type History from '../modules/history'; +import type Keyboard from '../modules/keyboard'; +import type Uploader from '../modules/uploader'; import Editor from './editor'; -import Emitter, { EmitterSource } from './emitter'; +import Emitter from './emitter'; +import type { EmitterSource } from './emitter'; import instances from './instances'; -import logger, { DebugLevel } from './logger'; +import logger from './logger'; +import type { DebugLevel } from './logger'; import Module from './module'; -import Selection, { Bounds, Range } from './selection'; +import Selection, { Range } from './selection'; +import type { Bounds } from './selection'; import Composition from './composition'; -import Theme, { ThemeConstructor } from './theme'; -import scrollRectIntoView, { Rect } from './utils/scrollRectIntoView'; +import Theme from './theme'; +import type { ThemeConstructor } from './theme'; +import scrollRectIntoView from './utils/scrollRectIntoView'; +import type { Rect } from './utils/scrollRectIntoView'; const debug = logger('quill'); diff --git a/core/selection.ts b/core/selection.ts index e05924a5b9..9bcef6162f 100644 --- a/core/selection.ts +++ b/core/selection.ts @@ -1,10 +1,11 @@ import { LeafBlot, Scope } from 'parchment'; import cloneDeep from 'lodash.clonedeep'; import isEqual from 'lodash.isequal'; -import Emitter, { EmitterSource } from './emitter'; +import Emitter from './emitter'; +import type { EmitterSource } from './emitter'; import logger from './logger'; -import Cursor from '../blots/cursor'; -import Scroll from '../blots/scroll'; +import type Cursor from '../blots/cursor'; +import type Scroll from '../blots/scroll'; const debug = logger('quill:selection'); @@ -173,7 +174,7 @@ class Selection { this.update(); } - getBounds(index: number, length = 0): Bounds | null { + getBounds(index: number, length = 0) { const scrollLength = this.scroll.length(); index = Math.min(index, scrollLength - 1); length = Math.min(index + length, scrollLength - 1) - index; diff --git a/core/theme.ts b/core/theme.ts index 85c91cad64..7a758cd730 100644 --- a/core/theme.ts +++ b/core/theme.ts @@ -1,9 +1,9 @@ -import Quill from '../core'; -import Clipboard from '../modules/clipboard'; -import History from '../modules/history'; -import Keyboard from '../modules/keyboard'; -import { ToolbarProps } from '../modules/toolbar'; -import Uploader from '../modules/uploader'; +import type Quill from '../core'; +import type Clipboard from '../modules/clipboard'; +import type History from '../modules/history'; +import type Keyboard from '../modules/keyboard'; +import type { ToolbarProps } from '../modules/toolbar'; +import type Uploader from '../modules/uploader'; export interface ThemeOptions { modules: Record & { diff --git a/e2e/history.spec.ts b/e2e/history.spec.ts index d568773718..04992024d0 100644 --- a/e2e/history.spec.ts +++ b/e2e/history.spec.ts @@ -1,4 +1,5 @@ -import { Page, expect } from '@playwright/test'; +import { expect } from '@playwright/test'; +import type { Page } from '@playwright/test'; import { test } from './fixtures'; import { SHORTKEY } from './utils'; diff --git a/formats/list.ts b/formats/list.ts index 3c0fa6fea3..b36f53d29e 100644 --- a/formats/list.ts +++ b/formats/list.ts @@ -1,6 +1,6 @@ import Block from '../blots/block'; import Container from '../blots/container'; -import Scroll from '../blots/scroll'; +import type Scroll from '../blots/scroll'; import Quill from '../core/quill'; class ListContainer extends Container {} diff --git a/formats/table.ts b/formats/table.ts index 18728c5e6a..8422b3d64e 100644 --- a/formats/table.ts +++ b/formats/table.ts @@ -1,4 +1,4 @@ -import { LinkedList } from 'parchment'; +import type { LinkedList } from 'parchment'; import Block from '../blots/block'; import Container from '../blots/container'; diff --git a/modules/clipboard.ts b/modules/clipboard.ts index b6e7264705..b8e480f440 100644 --- a/modules/clipboard.ts +++ b/modules/clipboard.ts @@ -1,19 +1,19 @@ +import type { ScrollBlot } from 'parchment'; import { Attributor, BlockBlot, ClassAttributor, EmbedBlot, Scope, - ScrollBlot, StyleAttributor, } from 'parchment'; import Delta from 'quill-delta'; import { BlockEmbed } from '../blots/block'; -import { EmitterSource } from '../core/emitter'; +import type { EmitterSource } from '../core/emitter'; import logger from '../core/logger'; import Module from '../core/module'; import Quill from '../core/quill'; -import { Range } from '../core/selection'; +import type { Range } from '../core/selection'; import { AlignAttribute, AlignStyle } from '../formats/align'; import { BackgroundStyle } from '../formats/background'; import CodeBlock from '../formats/code'; diff --git a/modules/history.ts b/modules/history.ts index b209668b62..a6ff519347 100644 --- a/modules/history.ts +++ b/modules/history.ts @@ -1,9 +1,9 @@ import { Scope } from 'parchment'; -import Delta from 'quill-delta'; +import type Delta from 'quill-delta'; import Module from '../core/module'; import Quill from '../core/quill'; import type Scroll from '../blots/scroll'; -import { Range } from '../core/selection'; +import type { Range } from '../core/selection'; export interface HistoryOptions { userOnly: boolean; diff --git a/modules/keyboard.ts b/modules/keyboard.ts index e7e22230bb..04f642178e 100644 --- a/modules/keyboard.ts +++ b/modules/keyboard.ts @@ -1,12 +1,13 @@ import cloneDeep from 'lodash.clonedeep'; import isEqual from 'lodash.isequal'; import Delta, { AttributeMap } from 'quill-delta'; -import { BlockBlot, Blot, EmbedBlot, Scope, TextBlot } from 'parchment'; +import { EmbedBlot, Scope, TextBlot } from 'parchment'; +import type { Blot, BlockBlot } from 'parchment'; import Quill from '../core/quill'; import logger from '../core/logger'; import Module from '../core/module'; -import { BlockEmbed } from '../blots/block'; -import { Range } from '../core/selection'; +import type { BlockEmbed } from '../blots/block'; +import type { Range } from '../core/selection'; const debug = logger('quill:keyboard'); diff --git a/modules/syntax.ts b/modules/syntax.ts index be7a680ee4..95a3c39c29 100644 --- a/modules/syntax.ts +++ b/modules/syntax.ts @@ -1,5 +1,6 @@ import Delta from 'quill-delta'; -import { Blot, ClassAttributor, Scope, ScrollBlot } from 'parchment'; +import { ClassAttributor, Scope } from 'parchment'; +import type { Blot, ScrollBlot } from 'parchment'; import Inline from '../blots/inline'; import Quill from '../core/quill'; import Module from '../core/module'; diff --git a/modules/tableEmbed.ts b/modules/tableEmbed.ts index b44ca354cc..783e1a16a8 100644 --- a/modules/tableEmbed.ts +++ b/modules/tableEmbed.ts @@ -1,5 +1,5 @@ -import Delta, { AttributeMap, OpIterator } from 'quill-delta'; -import Op from 'quill-delta/dist/Op'; +import Delta, { OpIterator } from 'quill-delta'; +import type { Op, AttributeMap } from 'quill-delta'; import Module from '../core/module'; export type CellData = { diff --git a/modules/toolbar.ts b/modules/toolbar.ts index f5c2b20ecb..4c6627d8bc 100644 --- a/modules/toolbar.ts +++ b/modules/toolbar.ts @@ -3,7 +3,7 @@ import { EmbedBlot, Scope } from 'parchment'; import Quill from '../core/quill'; import logger from '../core/logger'; import Module from '../core/module'; -import { Range } from '../core/selection'; +import type { Range } from '../core/selection'; const debug = logger('quill:toolbar'); diff --git a/modules/uploader.ts b/modules/uploader.ts index c91403fde7..3494010139 100644 --- a/modules/uploader.ts +++ b/modules/uploader.ts @@ -1,8 +1,8 @@ import Delta from 'quill-delta'; -import Quill from '../core/quill'; +import type Quill from '../core/quill'; import Emitter from '../core/emitter'; import Module from '../core/module'; -import { Range } from '../core/selection'; +import type { Range } from '../core/selection'; interface UploaderOptions { mimetypes: string[]; diff --git a/test/fuzz/editor.spec.ts b/test/fuzz/editor.spec.ts index 9505ece93d..91547c80ad 100644 --- a/test/fuzz/editor.spec.ts +++ b/test/fuzz/editor.spec.ts @@ -1,4 +1,5 @@ -import Delta, { AttributeMap, Op } from 'quill-delta'; +import type { Op } from 'quill-delta'; +import Delta, { AttributeMap } from 'quill-delta'; import { choose, randomInt, runFuzz } from './__helpers__/utils'; import { AlignClass } from '../../formats/align'; import { FontClass } from '../../formats/font'; diff --git a/test/fuzz/tableEmbed.spec.ts b/test/fuzz/tableEmbed.spec.ts index 7e5e155887..391477d636 100644 --- a/test/fuzz/tableEmbed.spec.ts +++ b/test/fuzz/tableEmbed.spec.ts @@ -1,5 +1,7 @@ -import Delta, { AttributeMap } from 'quill-delta'; -import TableEmbed, { +import type { AttributeMap } from 'quill-delta'; +import Delta from 'quill-delta'; +import TableEmbed from '../../modules/tableEmbed'; +import type { CellData, TableData, TableRowColumnOp, diff --git a/test/unit/core/quill.spec.ts b/test/unit/core/quill.spec.ts index d974a66b85..ce1cbb9aa9 100644 --- a/test/unit/core/quill.spec.ts +++ b/test/unit/core/quill.spec.ts @@ -1,13 +1,7 @@ import '../../../quill'; import Delta from 'quill-delta'; -import { - MockedFunction, - beforeEach, - describe, - expect, - test, - vitest, -} from 'vitest'; +import { beforeEach, describe, expect, test, vitest } from 'vitest'; +import type { MockedFunction } from 'vitest'; import Emitter from '../../../core/emitter'; import Theme from '../../../core/theme'; import Toolbar from '../../../modules/toolbar'; diff --git a/test/unit/modules/history.spec.ts b/test/unit/modules/history.spec.ts index ebf6aceeef..4e491b1131 100644 --- a/test/unit/modules/history.spec.ts +++ b/test/unit/modules/history.spec.ts @@ -1,7 +1,8 @@ import Delta from 'quill-delta'; import { describe, expect, test, vitest } from 'vitest'; import Quill from '../../../core'; -import { HistoryOptions, getLastChangeIndex } from '../../../modules/history'; +import { getLastChangeIndex } from '../../../modules/history'; +import type { HistoryOptions } from '../../../modules/history'; import { createRegistry, createScroll } from '../__helpers__/factory'; import { sleep } from '../__helpers__/utils'; import Bold from '../../../formats/bold'; diff --git a/test/unit/modules/keyboard.spec.ts b/test/unit/modules/keyboard.spec.ts index 5a91d1a4b7..690bc3d016 100644 --- a/test/unit/modules/keyboard.spec.ts +++ b/test/unit/modules/keyboard.spec.ts @@ -1,6 +1,13 @@ import { describe, expect, test } from 'vitest'; import Keyboard, { SHORTKEY, normalize } from '../../../modules/keyboard'; +const assert = (value: T | null | undefined): T => { + if (value == null) { + throw new Error(); + } + return value; +}; + const createKeyboardEvent = (key: string, override?: Partial) => new KeyboardEvent('keydown', { key, @@ -17,9 +24,14 @@ describe('Keyboard', () => { const binding = normalize({ key: 'a', }); - expect(Keyboard.match(createKeyboardEvent('a'), binding!)).toBe(true); + expect(Keyboard.match(createKeyboardEvent('a'), assert(binding))).toBe( + true, + ); expect( - Keyboard.match(createKeyboardEvent('A', { altKey: true }), binding!), + Keyboard.match( + createKeyboardEvent('A', { altKey: true }), + assert(binding), + ), ).toBe(false); }); @@ -28,9 +40,14 @@ describe('Keyboard', () => { key: 'a', altKey: true, }); - expect(Keyboard.match(createKeyboardEvent('a'), binding!)).toBe(false); + expect(Keyboard.match(createKeyboardEvent('a'), assert(binding))).toBe( + false, + ); expect( - Keyboard.match(createKeyboardEvent('a', { altKey: true }), binding!), + Keyboard.match( + createKeyboardEvent('a', { altKey: true }), + assert(binding), + ), ).toBe(true); }); @@ -39,9 +56,14 @@ describe('Keyboard', () => { key: 'a', altKey: null, }); - expect(Keyboard.match(createKeyboardEvent('a'), binding!)).toBe(true); + expect(Keyboard.match(createKeyboardEvent('a'), assert(binding))).toBe( + true, + ); expect( - Keyboard.match(createKeyboardEvent('a', { altKey: true }), binding!), + Keyboard.match( + createKeyboardEvent('a', { altKey: true }), + assert(binding), + ), ).toBe(true); }); @@ -50,11 +72,13 @@ describe('Keyboard', () => { key: 'a', shortKey: true, }); - expect(Keyboard.match(createKeyboardEvent('a'), binding!)).toBe(false); + expect(Keyboard.match(createKeyboardEvent('a'), assert(binding))).toBe( + false, + ); expect( Keyboard.match( createKeyboardEvent('a', { [SHORTKEY]: true }), - binding!, + assert(binding), ), ).toBe(true); }); @@ -64,11 +88,13 @@ describe('Keyboard', () => { key: 'a', [SHORTKEY]: true, }); - expect(Keyboard.match(createKeyboardEvent('a'), binding!)).toBe(false); + expect(Keyboard.match(createKeyboardEvent('a'), assert(binding))).toBe( + false, + ); expect( Keyboard.match( createKeyboardEvent('a', { [SHORTKEY]: true }), - binding!, + assert(binding), ), ).toBe(true); }); diff --git a/themes/base.ts b/themes/base.ts index ac5bb78dce..2bc1268ac4 100644 --- a/themes/base.ts +++ b/themes/base.ts @@ -1,17 +1,18 @@ import merge from 'lodash.merge'; -import Quill from '../core/quill'; +import type Quill from '../core/quill'; import Emitter from '../core/emitter'; -import Theme, { ThemeOptions } from '../core/theme'; +import Theme from '../core/theme'; +import type { ThemeOptions } from '../core/theme'; import ColorPicker from '../ui/color-picker'; import IconPicker from '../ui/icon-picker'; import Picker from '../ui/picker'; import Tooltip from '../ui/tooltip'; -import { Range } from '../core/selection'; -import Clipboard from '../modules/clipboard'; -import History from '../modules/history'; -import Keyboard from '../modules/keyboard'; -import Uploader from '../modules/uploader'; -import Selection from '../core/selection'; +import type { Range } from '../core/selection'; +import type Clipboard from '../modules/clipboard'; +import type History from '../modules/history'; +import type Keyboard from '../modules/keyboard'; +import type Uploader from '../modules/uploader'; +import type Selection from '../core/selection'; const ALIGNS = [false, 'center', 'right', 'justify']; diff --git a/themes/bubble.ts b/themes/bubble.ts index 0cb1695c07..6c0fcd5525 100644 --- a/themes/bubble.ts +++ b/themes/bubble.ts @@ -1,11 +1,13 @@ import merge from 'lodash.merge'; import Emitter from '../core/emitter'; import BaseTheme, { BaseTooltip } from './base'; -import { Bounds, Range } from '../core/selection'; +import { Range } from '../core/selection'; +import type { Bounds } from '../core/selection'; import icons from '../ui/icons'; -import Quill from '../core'; -import { ThemeOptions } from '../core/theme'; -import Toolbar, { ToolbarConfig } from '../modules/toolbar'; +import type Quill from '../core'; +import type { ThemeOptions } from '../core/theme'; +import type Toolbar from '../modules/toolbar'; +import type { ToolbarConfig } from '../modules/toolbar'; const TOOLBAR_CONFIG: ToolbarConfig = [ ['bold', 'italic', 'link'], diff --git a/themes/snow.ts b/themes/snow.ts index ea61d54f7b..43b2556fb9 100644 --- a/themes/snow.ts +++ b/themes/snow.ts @@ -4,10 +4,11 @@ import BaseTheme, { BaseTooltip } from './base'; import LinkBlot from '../formats/link'; import { Range } from '../core/selection'; import icons from '../ui/icons'; -import Quill from '../core'; -import { Context } from '../modules/keyboard'; -import Toolbar, { ToolbarConfig } from '../modules/toolbar'; -import { ThemeOptions } from '../core/theme'; +import type Quill from '../core'; +import type { Context } from '../modules/keyboard'; +import type Toolbar from '../modules/toolbar'; +import type { ToolbarConfig } from '../modules/toolbar'; +import type { ThemeOptions } from '../core/theme'; const TOOLBAR_CONFIG: ToolbarConfig = [ [{ header: ['1', '2', '3', false] }], diff --git a/tsconfig.json b/tsconfig.json index 806136d166..3ba16e62c6 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -9,6 +9,7 @@ "noEmit": true, "strictNullChecks": true, "noImplicitAny": true, + "verbatimModuleSyntax": true, "noUnusedLocals": true }, "include": ["./**/*"] diff --git a/ui/tooltip.ts b/ui/tooltip.ts index 5412a6ddd8..82ff487609 100644 --- a/ui/tooltip.ts +++ b/ui/tooltip.ts @@ -1,5 +1,5 @@ -import Quill from '../core'; -import { Bounds } from '../core/selection'; +import type Quill from '../core'; +import type { Bounds } from '../core/selection'; const isScrollable = (el: Element) => { const { overflowY } = getComputedStyle(el, null);