Skip to content

Commit

Permalink
Improve types for quill
Browse files Browse the repository at this point in the history
  • Loading branch information
luin committed Aug 13, 2023
1 parent 6c06286 commit 691377c
Show file tree
Hide file tree
Showing 4 changed files with 41 additions and 54 deletions.
75 changes: 27 additions & 48 deletions core/quill.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,18 +13,16 @@ import Emitter, { EmitterSource } from './emitter';
import instances from './instances';
import logger, { DebugLevel } from './logger';
import Module from './module';
import Selection, { Range } from './selection';
import Selection, { Bounds, Range } from './selection';
import Composition from './composition';
import Theme from './theme';
import Theme, { ThemeConstructor } from './theme';
import scrollRectIntoView, { Rect } from './utils/scrollRectIntoView';

const debug = logger('quill');

const globalRegistry = new Parchment.Registry();
Parchment.ParentBlot.uiClass = 'ql-ui';

export type Sources = 'api' | 'silent' | 'user';

interface Options {
theme?: string;
debug?: DebugLevel | boolean;
Expand All @@ -37,23 +35,13 @@ interface Options {
}

interface ExpandedOptions extends Omit<Options, 'theme'> {
theme?: typeof Theme;
registry?: Parchment.Registry;
container?: HTMLElement | string;
theme: ThemeConstructor;
registry: Parchment.Registry;
container: HTMLElement;
modules: Record<string, unknown>;
bounds?: HTMLElement | string | null;
[key: string]: unknown;
bounds?: HTMLElement | null;
}

export type BoundsStatic = {
bottom: number;
height: number;
left: number;
right: number;
top: number;
width: number;
};

class Quill {
static DEFAULTS: Partial<Options> = {
bounds: null,
Expand Down Expand Up @@ -159,19 +147,11 @@ class Quill {

constructor(container: HTMLElement | string, options: Options = {}) {
this.options = expandConfig(container, options);
if (this.options.container == null) {
this.container = this.options.container;
if (this.container == null) {
debug.error('Invalid Quill container', container);
return;
}
if (this.options.container instanceof HTMLElement) {
this.container = this.options.container;
}
if (typeof this.options.container === 'string') {
const el = document.querySelector<HTMLElement>(this.options.container);
if (el != null) {
this.container = el;
}
}
if (this.options.debug) {
Quill.debug(this.options.debug);
}
Expand All @@ -182,21 +162,17 @@ class Quill {
this.root = this.addContainer('ql-editor');
this.root.classList.add('ql-blank');
this.emitter = new Emitter();
if (this.options.registry) {
// @ts-expect-error TODO: fix BlotConstructor
const ScrollBlot = this.options.registry.query(
Parchment.ScrollBlot.blotName,
) as ScrollConstructor;
this.scroll = new ScrollBlot(this.options.registry, this.root, {
emitter: this.emitter,
});
}
// @ts-expect-error TODO: fix BlotConstructor
const ScrollBlot = this.options.registry.query(
Parchment.ScrollBlot.blotName,
) as ScrollConstructor;
this.scroll = new ScrollBlot(this.options.registry, this.root, {
emitter: this.emitter,
});
this.editor = new Editor(this.scroll);
this.selection = new Selection(this.scroll, this.emitter);
this.composition = new Composition(this.scroll, this.emitter);
if (this.options.theme) {
this.theme = new this.options.theme(this, this.options); // eslint-disable-line new-cap
}
this.theme = new this.options.theme(this, this.options); // eslint-disable-line new-cap
this.keyboard = this.theme.addModule('keyboard');
this.clipboard = this.theme.addModule('clipboard');
this.history = this.theme.addModule('history');
Expand Down Expand Up @@ -428,8 +404,8 @@ class Quill {
);
}

getBounds(index: number | Range, length = 0): BoundsStatic | null {
let bounds;
getBounds(index: number | Range, length = 0): Bounds | null {
let bounds: Bounds | null = null;
if (typeof index === 'number') {
bounds = this.selection.getBounds(index, length);
} else {
Expand Down Expand Up @@ -758,13 +734,14 @@ function expandConfig(
if (!expandedConfig.theme || expandedConfig.theme === Quill.DEFAULTS.theme) {
expandedConfig.theme = Theme;
} else {
expandedConfig.theme = Quill.import(`themes/${userConfig.theme}`);
expandedConfig.theme = Quill.import(`themes/${expandedConfig.theme}`);
if (expandedConfig.theme == null) {
throw new Error(
`Invalid theme ${expandedConfig.theme}. Did you register it?`,
);
}
}
// @ts-expect-error -- TODO fix this later
const themeConfig = cloneDeep(expandedConfig.theme.DEFAULTS);
[themeConfig, expandedConfig].forEach(config => {
config.modules = config.modules || {};
Expand Down Expand Up @@ -806,10 +783,11 @@ function expandConfig(
themeConfig,
expandedConfig,
);
['bounds', 'container'].forEach(key => {
(['bounds', 'container'] as const).forEach(key => {
const selector = expandedConfig[key];
if (typeof selector === 'string') {
expandedConfig[key] = document.querySelector(selector);
// @ts-expect-error Handle null case
expandedConfig[key] = document.querySelector(selector) as HTMLElement;
}
});
expandedConfig.modules = Object.keys(expandedConfig.modules).reduce(
Expand Down Expand Up @@ -848,7 +826,8 @@ function modify(
}
if (shift == null) {
range = shiftRange(range, change, source);
} else if (shift !== 0 && typeof index === 'number') {
} else if (shift !== 0) {
// @ts-expect-error index should always be number
range = shiftRange(range, index, shift, source);
}
this.setSelection(range, Emitter.sources.SILENT);
Expand Down Expand Up @@ -963,10 +942,10 @@ function shiftRange(
function shiftRange(
range: Range,
index: number | Delta,
_length?: number | EmitterSource,
lengthOrSource?: number | EmitterSource,
source?: EmitterSource,
) {
const length = typeof _length === 'number' ? _length : 0;
const length = typeof lengthOrSource === 'number' ? lengthOrSource : 0;
if (range == null) return null;
let start;
let end;
Expand Down
11 changes: 10 additions & 1 deletion core/selection.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,15 @@ interface NormalizedRange {
native: NativeRange;
}

export interface Bounds {
bottom: number;
height: number;
left: number;
right: number;
top: number;
width: number;
}

class Range {
constructor(public index: number, public length = 0) {}
}
Expand Down Expand Up @@ -164,7 +173,7 @@ class Selection {
this.update();
}

getBounds(index: number, length = 0) {
getBounds(index: number, length = 0): Bounds | null {
const scrollLength = this.scroll.length();
index = Math.min(index, scrollLength - 1);
length = Math.min(index + length, scrollLength - 1) - index;
Expand Down
5 changes: 2 additions & 3 deletions themes/bubble.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
import merge from 'lodash.merge';
import Emitter from '../core/emitter';
import BaseTheme, { BaseTooltip } from './base';
import { Range } from '../core/selection';
import { Bounds, Range } from '../core/selection';
import icons from '../ui/icons';
import Quill from '../core';
import { BoundsStatic } from '../core/quill';
import { ThemeOptions } from '../core/theme';
import Toolbar, { ToolbarConfig } from '../modules/toolbar';

Expand Down Expand Up @@ -91,7 +90,7 @@ class BubbleTooltip extends BaseTooltip {
this.show();
}

position(reference: BoundsStatic) {
position(reference: Bounds) {
const shift = super.position(reference);
const arrow = this.root.querySelector('.ql-tooltip-arrow');
// @ts-expect-error
Expand Down
4 changes: 2 additions & 2 deletions ui/tooltip.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import Quill from '../core';
import { BoundsStatic } from '../core/quill';
import { Bounds } from '../core/selection';

const isScrollable = (el: Element) => {
const { overflowY } = getComputedStyle(el, null);
Expand Down Expand Up @@ -29,7 +29,7 @@ class Tooltip {
this.root.classList.add('ql-hidden');
}

position(reference: BoundsStatic) {
position(reference: Bounds) {
const left =
reference.left + reference.width / 2 - this.root.offsetWidth / 2;
// root.scrollTop should be 0 if scrollContainer !== root
Expand Down

0 comments on commit 691377c

Please sign in to comment.