Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions packages/quill/src/core.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import Delta, { Op, OpIterator, AttributeMap } from 'quill-delta';
import Input from './modules/input.js';
import UINode from './modules/uiNode.js';

export { default as Module } from './core/module.js';
export { Delta, Op, OpIterator, AttributeMap, Parchment, Range };
export type {
Bounds,
Expand Down
47 changes: 29 additions & 18 deletions packages/quill/src/core/quill.ts
Original file line number Diff line number Diff line change
Expand Up @@ -122,27 +122,41 @@ class Quill {
}

static register(
path:
| string
| Parchment.BlotConstructor
| Parchment.Attributor
| Record<string, unknown>,
target?: Parchment.BlotConstructor | Parchment.Attributor | boolean,
overwrite = false,
) {
if (typeof path !== 'string') {
const name = 'attrName' in path ? path.attrName : path.blotName;
targets: Record<
string,
| Parchment.RegistryDefinition
| Record<string, unknown> // any objects
| Theme
| Module
| Function // ES5 constructors
>,
overwrite?: boolean,
): void;
static register(
target: Parchment.RegistryDefinition,
overwrite?: boolean,
): void;
static register(path: string, target: any, overwrite?: boolean): void;
static register(...args: any[]): void {
if (typeof args[0] !== 'string') {
const target = args[0];
const overwrite = !!args[1];

const name = 'attrName' in target ? target.attrName : target.blotName;
if (typeof name === 'string') {
// Shortcut for formats:
// register(Blot | Attributor, overwrite)
// @ts-expect-error
this.register(`formats/${name}`, path, target);
this.register(`formats/${name}`, target, overwrite);
} else {
Object.keys(path).forEach((key) => {
// @ts-expect-error
this.register(key, path[key], target);
Object.keys(target).forEach((key) => {
this.register(key, target[key], overwrite);
});
}
} else {
const path = args[0];
const target = args[1];
const overwrite = !!args[2];

if (this.imports[path] != null && !overwrite) {
debug.warn(`Overwriting ${path} with`, target);
}
Expand All @@ -151,14 +165,11 @@ class Quill {
(path.startsWith('blots/') || path.startsWith('formats/')) &&
target &&
typeof target !== 'boolean' &&
// @ts-expect-error
target.blotName !== 'abstract'
) {
globalRegistry.register(target);
}
// @ts-expect-error
if (typeof target.register === 'function') {
// @ts-expect-error
target.register(globalRegistry);
}
}
Expand Down
5 changes: 2 additions & 3 deletions packages/quill/src/modules/syntax.ts
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ class SyntaxCodeBlock extends CodeBlock {
}
}

replaceWith(name: string, value: unknown) {
replaceWith(name: string | Blot, value?: any) {
this.formatAt(0, this.length(), CodeToken.blotName, false);
return super.replaceWith(name, value);
}
Expand Down Expand Up @@ -180,7 +180,7 @@ class SyntaxCodeBlockContainer extends CodeBlockContainer {
}
}
}
// @ts-expect-error

SyntaxCodeBlockContainer.allowedChildren = [SyntaxCodeBlock];
SyntaxCodeBlock.requiredContainer = SyntaxCodeBlockContainer;
SyntaxCodeBlock.allowedChildren = [CodeToken, CursorBlot, TextBlot, BreakBlot];
Expand All @@ -206,7 +206,6 @@ class Syntax extends Module<SyntaxOptions> {

static register() {
Quill.register(CodeToken, true);
// @ts-expect-error
Quill.register(SyntaxCodeBlock, true);
Quill.register(SyntaxCodeBlockContainer, true);
}
Expand Down
1 change: 1 addition & 0 deletions packages/quill/src/quill.ts
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,7 @@ Quill.register(
true,
);

export { Module } from './core.js';
export type {
Bounds,
DebugLevel,
Expand Down
31 changes: 31 additions & 0 deletions packages/quill/test/types/quill.test-d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,37 @@ import Quill from '../../src/quill.js';
import type { EmitterSource, Parchment, Range } from '../../src/quill.js';
import Delta from 'quill-delta';
import type { default as Block, BlockEmbed } from '../../src/blots/block.js';
import SnowTheme from '../../src/themes/snow.js';
import { LeafBlot } from 'parchment';

{
const Counter = (quill: Quill, options: { unit: string }) => {
console.log(quill, options);
};
Quill.register('modules/counter', Counter);
Quill.register('themes/snow', SnowTheme);
Quill.register('themes/snow', SnowTheme, true);

class MyBlot extends LeafBlot {}

Quill.register(MyBlot);
Quill.register(MyBlot, true);
// @ts-expect-error
Quill.register(SnowTheme);
Quill.register({
'modules/counter': Counter,
'themes/snow': SnowTheme,
'formats/my-blot': MyBlot,
});
Quill.register(
{
'modules/counter': Counter,
'themes/snow': SnowTheme,
'formats/my-blot': MyBlot,
},
true,
);
}

const quill = new Quill('#editor');

Expand Down
45 changes: 43 additions & 2 deletions packages/quill/test/unit/core/quill.spec.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import '../../../src/quill.js';
import Delta from 'quill-delta';
import { Registry } from 'parchment';
import { beforeEach, describe, expect, test, vitest } from 'vitest';
import { LeafBlot, Registry } from 'parchment';
import { afterEach, beforeEach, describe, expect, test, vitest } from 'vitest';
import type { MockedFunction } from 'vitest';
import Emitter from '../../../src/core/emitter.js';
import Theme from '../../../src/core/theme.js';
Expand Down Expand Up @@ -29,6 +29,47 @@ describe('Quill', () => {
});
});

describe('register', () => {
const imports = { ...Quill.imports };
afterEach(() => {
Quill.imports = imports;
});

test('register(path, target)', () => {
class Counter {}
Quill.register('modules/counter', Counter);

expect(Quill.imports).toHaveProperty('modules/counter', Counter);
expect(Quill.import('modules/counter')).toEqual(Counter);
});

test('register(formats)', () => {
class MyCounterBlot extends LeafBlot {
static blotName = 'my-counter';
static className = 'ql-my-counter';
}
Quill.register(MyCounterBlot);

expect(Quill.imports).toHaveProperty('formats/my-counter', MyCounterBlot);
expect(Quill.import('formats/my-counter')).toEqual(MyCounterBlot);
});

test('register(targets)', () => {
class ABlot extends LeafBlot {
static blotName = 'a-blot';
static className = 'ql-a-blot';
}
class AModule {}
Quill.register({
'formats/a-blot': ABlot,
'modules/a-module': AModule,
});

expect(Quill.import('formats/a-blot')).toEqual(ABlot);
expect(Quill.import('modules/a-module')).toEqual(AModule);
});
});

describe('construction', () => {
test('empty', () => {
const quill = new Quill(createContainer());
Expand Down