Two build targets — core and full
dist/ribbit/ribbit-core.js — editor without extra features dist/ribbit/ribbit.js — editor with all features Added a theme feature flag for vim keybindings
This commit is contained in:
parent
3368e719fd
commit
2e28598243
|
|
@ -7,10 +7,12 @@
|
|||
"dist/ribbit/"
|
||||
],
|
||||
"scripts": {
|
||||
"build": "mkdir -p dist/ribbit && npm run build:check && npm run build:js && npm run build:min && npm run build:css",
|
||||
"build": "mkdir -p dist/ribbit && npm run build:check && npm run build:js && npm run build:min && npm run build:core && npm run build:core-min && npm run build:css",
|
||||
"build:check": "tsc --noEmit",
|
||||
"build:js": "esbuild src/ts/ribbit-editor.ts --bundle --format=iife --global-name=ribbit --sourcemap --outfile=dist/ribbit/ribbit.js",
|
||||
"build:min": "esbuild src/ts/ribbit-editor.ts --bundle --format=iife --global-name=ribbit --minify --outfile=dist/ribbit/ribbit.min.js",
|
||||
"build:core": "esbuild src/ts/ribbit-core.ts --bundle --format=iife --global-name=ribbit --sourcemap --outfile=dist/ribbit/ribbit-core.js",
|
||||
"build:core-min": "esbuild src/ts/ribbit-core.ts --bundle --format=iife --global-name=ribbit --minify --outfile=dist/ribbit/ribbit-core.min.js",
|
||||
"build:css": "cp src/static/ribbit-core.css dist/ribbit/ && cp -r src/static/themes dist/ribbit/",
|
||||
"test": "npm run build && jest --verbose",
|
||||
"test:coverage": "npm run build && jest --coverage"
|
||||
|
|
|
|||
21
src/ts/ribbit-core.ts
Normal file
21
src/ts/ribbit-core.ts
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
/*
|
||||
* ribbit-core.ts — lightweight entry point without optional features (vim).
|
||||
*
|
||||
* Same API as ribbit-editor.ts but excludes VimHandler.
|
||||
*/
|
||||
|
||||
import { HopDown } from './hopdown';
|
||||
import { defaultTags, defaultBlockTags, defaultInlineTags, inlineTag } from './tags';
|
||||
import { defaultTheme } from './default-theme';
|
||||
import { Ribbit, camelCase, decodeHtmlEntities, encodeHtmlEntities } from './ribbit';
|
||||
import { type MacroDef } from './macros';
|
||||
|
||||
export { RibbitEditor as Editor } from './ribbit-editor';
|
||||
export { Ribbit as Viewer };
|
||||
export { HopDown };
|
||||
export { inlineTag };
|
||||
export { defaultTags, defaultBlockTags, defaultInlineTags };
|
||||
export { defaultTheme };
|
||||
export { camelCase, decodeHtmlEntities, encodeHtmlEntities };
|
||||
export { ToolbarManager } from './toolbar';
|
||||
export type { MacroDef };
|
||||
|
|
@ -23,7 +23,7 @@ import { type MacroDef } from './macros';
|
|||
* editor.view(); // switch to read-only view
|
||||
*/
|
||||
export class RibbitEditor extends Ribbit {
|
||||
private vim!: VimHandler;
|
||||
private vim?: VimHandler;
|
||||
|
||||
run(): void {
|
||||
this.states = {
|
||||
|
|
@ -32,17 +32,19 @@ export class RibbitEditor extends Ribbit {
|
|||
WYSIWYG: 'wysiwyg'
|
||||
};
|
||||
|
||||
this.vim = new VimHandler((mode) => {
|
||||
if (mode === 'normal') {
|
||||
this.toolbar.disable();
|
||||
this.element.classList.add('vim-normal');
|
||||
this.element.classList.remove('vim-insert');
|
||||
} else {
|
||||
this.toolbar.enable();
|
||||
this.element.classList.add('vim-insert');
|
||||
this.element.classList.remove('vim-normal');
|
||||
}
|
||||
});
|
||||
if (this.theme.features?.vim) {
|
||||
this.vim = new VimHandler((mode) => {
|
||||
if (mode === 'normal') {
|
||||
this.toolbar.disable();
|
||||
this.element.classList.add('vim-normal');
|
||||
this.element.classList.remove('vim-insert');
|
||||
} else {
|
||||
this.toolbar.enable();
|
||||
this.element.classList.add('vim-insert');
|
||||
this.element.classList.remove('vim-normal');
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
this.#bindEvents();
|
||||
this.element.classList.add('loaded');
|
||||
|
|
@ -218,7 +220,7 @@ export class RibbitEditor extends Ribbit {
|
|||
|
||||
wysiwyg(): void {
|
||||
if (this.getState() === this.states.WYSIWYG) return;
|
||||
this.vim.detach();
|
||||
this.vim?.detach();
|
||||
this.element.contentEditable = 'true';
|
||||
this.element.innerHTML = this.getHTML();
|
||||
Array.from(this.element.querySelectorAll('.macro')).forEach(el => {
|
||||
|
|
@ -238,7 +240,7 @@ export class RibbitEditor extends Ribbit {
|
|||
if (this.state === this.states.EDIT) return;
|
||||
this.element.contentEditable = 'true';
|
||||
this.element.innerHTML = encodeHtmlEntities(this.getMarkdown());
|
||||
this.vim.attach(this.element);
|
||||
this.vim?.attach(this.element);
|
||||
this.setState(this.states.EDIT);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -68,6 +68,7 @@ export interface InlineTagDef {
|
|||
|
||||
export interface RibbitThemeFeatures {
|
||||
sourceMode?: boolean;
|
||||
vim?: boolean;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -6,14 +6,14 @@ describe('VimHandler', () => {
|
|||
beforeEach(() => resetDOM('hello world'));
|
||||
|
||||
it('starts in insert mode', () => {
|
||||
const editor = new r.Editor({});
|
||||
const editor = new r.Editor({ currentTheme: 'vim', themes: [{ name: 'vim', features: { sourceMode: true, vim: true }, tags: r.defaultTags }] });
|
||||
editor.run();
|
||||
editor.edit();
|
||||
expect(editor.element.classList.contains('vim-insert')).toBe(true);
|
||||
});
|
||||
|
||||
it('Esc enters normal mode', () => {
|
||||
const editor = new r.Editor({});
|
||||
const editor = new r.Editor({ currentTheme: 'vim', themes: [{ name: 'vim', features: { sourceMode: true, vim: true }, tags: r.defaultTags }] });
|
||||
editor.run();
|
||||
editor.edit();
|
||||
editor.element.dispatchEvent(new r.window.KeyboardEvent('keydown', { key: 'Escape' }));
|
||||
|
|
@ -22,7 +22,7 @@ describe('VimHandler', () => {
|
|||
});
|
||||
|
||||
it('i returns to insert mode', () => {
|
||||
const editor = new r.Editor({});
|
||||
const editor = new r.Editor({ currentTheme: 'vim', themes: [{ name: 'vim', features: { sourceMode: true, vim: true }, tags: r.defaultTags }] });
|
||||
editor.run();
|
||||
editor.edit();
|
||||
// Enter normal mode
|
||||
|
|
@ -34,7 +34,7 @@ describe('VimHandler', () => {
|
|||
});
|
||||
|
||||
it('disables toolbar in normal mode', () => {
|
||||
const editor = new r.Editor({ autoToolbar: false });
|
||||
const editor = new r.Editor({ autoToolbar: false, currentTheme: 'vim', themes: [{ name: 'vim', features: { sourceMode: true, vim: true }, tags: r.defaultTags }] });
|
||||
editor.run();
|
||||
editor.toolbar.render();
|
||||
editor.edit();
|
||||
|
|
@ -45,7 +45,7 @@ describe('VimHandler', () => {
|
|||
});
|
||||
|
||||
it('re-enables toolbar in insert mode', () => {
|
||||
const editor = new r.Editor({ autoToolbar: false });
|
||||
const editor = new r.Editor({ autoToolbar: false, currentTheme: 'vim', themes: [{ name: 'vim', features: { sourceMode: true, vim: true }, tags: r.defaultTags }] });
|
||||
editor.run();
|
||||
editor.toolbar.render();
|
||||
editor.edit();
|
||||
|
|
@ -56,7 +56,7 @@ describe('VimHandler', () => {
|
|||
});
|
||||
|
||||
it('detaches when leaving edit mode', () => {
|
||||
const editor = new r.Editor({});
|
||||
const editor = new r.Editor({ currentTheme: 'vim', themes: [{ name: 'vim', features: { sourceMode: true, vim: true }, tags: r.defaultTags }] });
|
||||
editor.run();
|
||||
editor.edit();
|
||||
editor.element.dispatchEvent(new r.window.KeyboardEvent('keydown', { key: 'Escape' }));
|
||||
|
|
@ -68,7 +68,7 @@ describe('VimHandler', () => {
|
|||
});
|
||||
|
||||
it('only activates in edit mode', () => {
|
||||
const editor = new r.Editor({});
|
||||
const editor = new r.Editor({ currentTheme: 'vim', themes: [{ name: 'vim', features: { sourceMode: true, vim: true }, tags: r.defaultTags }] });
|
||||
editor.run();
|
||||
editor.wysiwyg();
|
||||
// Esc in wysiwyg should not add vim classes
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user