Tài liệu API
AutumnNote v1.13.0 — Nhanh. Nhẹ. Đáng tin cậy. Hiệu quả.
Cài đặt
Cài đặt qua npm (hoặc pnpm / yarn):
npm install autumnnote
Hoặc dùng CDN — không cần bước build:
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/autumnnote/dist/autumnnote.css">
<script src="https://cdn.jsdelivr.net/npm/autumnnote"></script>
Framework Wrapper v1.6.0
Wrapper React và Vue 3 chính thức được phát hành dưới dạng các package riêng trong cùng pnpm workspace.
Mỗi wrapper là một lớp cầu nối lifecycle mỏng — nó mount một instance editor lên phần tử host và
expose object Context cho component cha thông qua ref.
React — autumnnote-react
Cài đặt wrapper cùng với core:
npm install autumnnote autumnnote-react
import { useRef } from 'react';
import AutumnNoteEditor from 'autumnnote-react';
import 'autumnnote/dist/autumnnote.css';
function MyEditor() {
const editorRef = useRef(null);
function handleSave() {
const html = editorRef.current.getHTML();
console.log(html);
}
return (
<>
<AutumnNoteEditor
ref={editorRef}
options={{
placeholder: 'Bắt đầu gõ…',
height: 300,
bubbleToolbar: true,
onChange: (html) => console.log(html),
}}
/>
<button onClick={handleSave}>Lưu</button>
</>
);
}
Component sử dụng forwardRef + useImperativeHandle để expose
instance Context bên dưới. Tất cả phương thức instance
(getHTML, setHTML, invoke, v.v.) đều truy cập được qua ref.
Editor khởi tạo một lần khi mount; để khởi tạo lại với tùy chọn mới, truyền một prop key mới.
Props:
| Prop | Kiểu | Mô tả |
|---|---|---|
| options | AsnOptions | Object cấu hình editor. Tất cả trường AsnOptions đều được chấp nhận. |
| className | string | CSS class áp dụng cho <div> container. |
| style | CSSProperties | Style inline áp dụng cho <div> container. |
| ref | React.Ref<Context> | Forwarded ref — expose instance Context. |
Vue 3 — autumnnote-vue
Cài đặt wrapper cùng với core:
npm install autumnnote autumnnote-vue
<script setup>
import { ref } from 'vue';
import AutumnNoteEditor from 'autumnnote-vue';
import 'autumnnote/dist/autumnnote.css';
const editorRef = ref(null);
function handleSave() {
const html = editorRef.value.editor.value.getHTML();
console.log(html);
}
</script>
<template>
<AutumnNoteEditor
ref="editorRef"
:options="{ placeholder: 'Bắt đầu gõ…', height: 300 }"
/>
<button @click="handleSave">Lưu</button>
</template>
Component sử dụng defineExpose({ editor }) trong đó editor là một
Vue ref<Context | null>. Truy cập instance qua
editorRef.value.editor.value. Editor được tạo trong onMounted
và hủy trong onUnmounted. Dùng v-if để buộc remount khi tùy chọn thay đổi.
Props:
| Prop | Kiểu | Mô tả |
|---|---|---|
| options | AsnOptions | Object cấu hình editor. Tất cả trường AsnOptions đều được chấp nhận. |
Bắt đầu nhanh
Bọc bất kỳ <textarea> hoặc <div> nào trong HTML của bạn:
import AutumnNote from 'autumnnote';
import 'autumnnote/dist/autumnnote.css';
const editor = AutumnNote.create('#editor', {
placeholder: 'Bắt đầu gõ…',
height: 300,
bubbleToolbar: true,
onChange(html) {
console.log('content changed:', html);
},
});
Lấy và đặt nội dung:
editor.setHTML('<p>Hello <strong>world</strong></p>');
const html = editor.getHTML();
const markdown = editor.getMarkdown();
editor.destroy(); // clean up when done
Tất cả tùy chọn 50+ tùy chọn
Truyền các tùy chọn này vào AutumnNote.create(selector, options) hoặc AutumnNote.setDefaults(options).
| Tùy chọn | Kiểu | Mặc định | Mô tả |
|---|---|---|---|
| placeholder | string | '' | Văn bản placeholder khi editor rỗng. |
| height | number | 200 | Chiều cao tối thiểu của editor (px). |
| minHeight | number | 100 | Chiều cao tối thiểu của vùng soạn thảo. |
| maxHeight | number | 0 | Chiều cao tối đa (px). 0 = không giới hạn. |
| focus | boolean | false | Tự động focus editor khi khởi tạo. |
| resizable | boolean | true | Hiện tay cầm kéo trong statusbar để thay đổi kích thước editor. |
| readOnly | boolean | false | Bắt đầu ở chế độ chỉ đọc (không chỉnh sửa). Bật/tắt lúc runtime bằng setDisabled(). |
| spellcheck | boolean | true | Bật kiểm tra chính tả của trình duyệt. |
| toolbar | Array<Array<…>> | defaultToolbar | Mảng 2 chiều gồm các nhóm nút. Mỗi phần tử là object ButtonDef hoặc tên chuỗi của một nút đã đăng ký. |
| stickyToolbar | boolean | false | Dính toolbar vào đầu viewport khi cuộn trang. |
| stickyToolbarOffset | number | 0 | Khoảng cách từ trên (px) cho toolbar dính (ví dụ: chiều cao thanh nav cố định). |
| toolbarOverflow | 'wrap' | 'scroll' | 'wrap' | Chiến lược tràn toolbar khi các nút không vừa một hàng. |
| bubbleToolbar | boolean | false | Hiện thanh công cụ nổi nhỏ phía trên văn bản được chọn. |
| bubbleToolbarItems | string[] | xem bên dưới | Tên các nút trong thanh công cụ nổi. Mặc định: ['bold','italic','underline','link','foreColor','hiliteColor','removeFormat']. |
| theme | 'light' | 'dark' | 'light' | Giao diện màu. Dùng 'dark' hoặc bật/tắt qua container.classList.add('an-theme-dark'). |
| focusColor | string | null | null | Màu viền focus tùy chỉnh (ví dụ: '#f97316'). |
| direction | 'ltr' | 'rtl' | 'ltr' | Hướng văn bản cho vùng soạn thảo. |
| defaultFontFamily | string | 'Arial' | Font mặc định áp dụng cho editor khi khởi tạo. |
| defaultFontSize | string | '14px' | Cỡ chữ mặc định. |
| fontFamilies | string[] | 10 font | Các tùy chọn hiển thị trong dropdown chọn font. |
| colorSwatches | string[] | [] | Các mã màu hex tùy chỉnh thêm vào đầu mọi color picker. |
| tabSize | number | 4 | Số khoảng trắng chèn vào mỗi lần nhấn Tab (trong khối mã). |
| maxChars | number | 0 | Số ký tự tối đa. 0 = không giới hạn. Hiện cảnh báo trong statusbar khi gần đạt giới hạn. |
| maxWords | number | 0 | Số từ tối đa. 0 = không giới hạn. |
| historyLimit | number | 100 | Số bước tối đa trong lịch sử hoàn tác/làm lại. |
| pasteAsPlainText | boolean | false | Ép paste dạng văn bản thuần — loại bỏ toàn bộ HTML. |
| pasteCleanHTML | boolean | true | Làm sạch HTML khi paste (loại bỏ script, event handler, v.v.). |
| pasteStripAttributes | boolean | false | Loại bỏ thuộc tính class, style, và data-* khỏi HTML được paste. |
| markdownPaste | boolean | true | Chuyển đổi Markdown được paste thành HTML. |
| markdownShortcuts | boolean | true | Kích hoạt Markdown nội dòng: **bold**, ## heading, - item, v.v. |
| allowImageUpload | boolean | true | Cho phép tải file lên trong hộp thoại chèn ảnh. |
| maxImageSize | number | 5 | Kích thước tối đa của ảnh tải lên (MB). |
| codeHighlight | boolean | true | Tự động tải Prism.js để tô sáng cú pháp trong khối mã. |
| codeHighlightCDN | string | Prism 1.29 CDN | URL gốc CDN của Prism (ghi đè để tự host). |
| autoSave | boolean | false | Lưu nội dung vào localStorage mỗi khi thay đổi. |
| autoSaveKey | string | 'autumnnote-autosave' | Key localStorage cho auto-save. |
| autoSaveRestore | boolean | false | Hiện banner khôi phục khi có bản nháp (yêu cầu autoSave: true). |
| autoSaveRestoreTimeout | number | 7 | Tuổi bản nháp tối đa (ngày) để khôi phục. 0 = không hết hạn. |
| useBootstrap | boolean | false | Áp dụng class nút Bootstrap cho các nút toolbar. |
| useFontAwesome | boolean | true | Hiển thị icon toolbar dạng Font Awesome glyph (yêu cầu CSS FA). |
| fontAwesomeClass | string | 'fas' | Class prefix FA ('fas' cho v5, 'fa-solid' cho v6). |
| tableHeaderRow | boolean | false | Chèn dòng <thead> khi tạo bảng. |
| mention | object | null | null | Cấu hình tự động gợi ý @mention. Xem tùy chọn mention. |
| lang | string | object | 'en' | Ngôn ngữ giao diện. Có sẵn: 'en' 'vi' 'ja' 'zh' 'fr' 'de' 'es' 'ko'. Truyền một object để ghi đè từng chuỗi riêng lẻ. |
Tùy chọn callback
| Tùy chọn | Signature | Mô tả |
|---|---|---|
| onChange | (html: string) => void | Kích hoạt khi nội dung thay đổi (có debounce). |
| onFocus | (ctx: Context) => void | Kích hoạt khi editor nhận focus. |
| onBlur | (ctx: Context) => void | Kích hoạt khi editor mất focus. |
| onInit | (ctx: Context) => void | Kích hoạt sau khi tất cả module đã khởi tạo xong. |
| onDestroy | (ctx: Context) => void | Kích hoạt trước khi editor bị hủy. |
| onSelectionChange | (ctx: Context) => void | Kích hoạt khi con trỏ hoặc vùng chọn thay đổi. |
| onPaste | (data: {text, html}) => void | Kích hoạt sau mỗi lần paste. |
| onImageUpload | (files: File[]) => void | Handler tải ảnh tùy chỉnh (thay thế nhúng inline mặc định). |
| onImageError | (err) => void | Kích hoạt khi tải ảnh thất bại. |
| onCharLimitReached | (ctx: Context) => void | Kích hoạt khi đạt maxChars. |
| onWordLimitReached | (ctx: Context) => void | Kích hoạt khi đạt maxWords. |
| onAutoSaveRestore | (html, ctx) => void | Kích hoạt sau khi người dùng khôi phục bản nháp. |
Phương thức tĩnh
Các phương thức trên chính object AutumnNote (không phải trên instance editor).
AutumnNote.create(selector, options?)
Tạo một hoặc nhiều instance editor. Trả về một Context đơn khi selector khớp một phần tử, hoặc một mảng khi khớp nhiều phần tử. Lưu cache các instance trong WeakMap — gọi create hai lần trên cùng một phần tử sẽ trả về instance đã cache.
const editor = AutumnNote.create('#my-editor', {
height: 350,
bubbleToolbar: true,
});
// Multiple elements
const editors = AutumnNote.create('.editor', { height: 200 });
AutumnNote.destroy(selector)
Hủy tất cả instance editor khớp với selector và khôi phục phần tử gốc.
AutumnNote.getInstance(selector)
Trả về Context của một phần tử cho trước, hoặc null nếu không có.
AutumnNote.setDefaults(options)
Gộp các tùy chọn vào mặc định toàn cục — áp dụng cho mọi lần gọi create() tiếp theo.
AutumnNote.setDefaults({
theme: 'dark',
bubbleToolbar: true,
lang: 'vi',
});
AutumnNote.resetDefaults()
Khôi phục mặc định toàn cục về giá trị gốc.
AutumnNote.registerModule(name, ModuleClass)
Đăng ký một module tùy chỉnh sẽ được đưa vào mọi instance editor tiếp theo. Module nhận object Context trong constructor và phải implement initialize(), tùy chọn destroy().
AutumnNote.use(plugin, options?)
Cài đặt một plugin toàn cục. Các buttons của plugin được đăng ký ngay lập tức (trước create()); install() được gọi sau khi tất cả module có sẵn khởi tạo xong. Xem Plugin API.
AutumnNote.hasPlugin(name)
Trả về true nếu một plugin với tên đã cho được đăng ký toàn cục.
AutumnNote.registerButton(btnDef)
Đăng ký một định nghĩa nút đơn vào registry toàn cục để có thể tham chiếu bằng tên chuỗi trong cấu hình toolbar. Gọi ctx.invoke('toolbar.rebuild') sau khi đăng ký trên một editor đang chạy.
AutumnNote.version
Chuỗi chứa phiên bản thư viện, ví dụ '1.3.0'.
Phương thức Instance
Các phương thức trên object Context trả về từ AutumnNote.create().
Nội dung
editor.getHTML()
Trả về nội dung hiện tại dưới dạng chuỗi HTML.
editor.setHTML(html)
Đặt nội dung editor. HTML được làm sạch trước khi chèn.
editor.getText()
Trả về nội dung dạng văn bản thuần (không thẻ HTML).
editor.setText(text)
Đặt nội dung văn bản thuần (đã escape HTML, bọc trong <p>).
editor.getMarkdown()
Chuyển nội dung hiện tại sang Markdown và trả về chuỗi.
editor.setMarkdown(md)
Chuyển Markdown sang HTML và đặt làm nội dung editor.
editor.insertHTML(html)
Chèn HTML tại vị trí con trỏ hiện tại.
editor.insertText(text)
Chèn văn bản thuần tại vị trí con trỏ hiện tại.
editor.clear()
Xóa toàn bộ nội dung editor.
editor.clearHistory()
Đặt lại stack lịch sử hoàn tác/làm lại.
editor.isEmpty()
Trả về true khi editor không có nội dung có ý nghĩa.
Trạng thái & Thông tin
editor.getWordCount()
Trả về số từ hiện tại (hỗ trợ CJK qua Intl.Segmenter).
editor.getCharCount()
Trả về số ký tự hiện tại (không tính xuống dòng).
editor.setDisabled(disabled)
Bật hoặc tắt editor. true = chỉ đọc, ẩn toolbar.
editor.downloadHTML(filename?) / .downloadText() / .downloadMarkdown()
Kích hoạt tải nội dung xuống trình duyệt theo định dạng chỉ định. Tên file mặc định: 'document.html', 'document.txt', 'document.md'.
editor.print(title?)
Mở nội dung trong cửa sổ mới và kích hoạt hộp thoại in của trình duyệt.
editor.invoke(path, ...args)
Gọi một phương thức trên module đã đăng ký. Định dạng: 'moduleName.methodName'.
editor.invoke('toolbar.rebuild'); // Rebuild toolbar after button registration
editor.invoke('editor.bold'); // Apply bold
editor.invoke('findReplace.show'); // Open Find dialog
editor.invoke('fullscreen.toggle'); // Toggle fullscreen
Sự kiện
editor.on(eventName, handler)
Đăng ký lắng nghe một sự kiện editor. Trả về hàm hủy đăng ký.
const unsub = editor.on('change', (html) => {
console.log('changed:', html);
});
// Later:
unsub(); // unsubscribe
editor.off(eventName, handler)
Hủy đăng ký một handler cụ thể khỏi sự kiện.
editor.registerModule(name, ModuleClass)
Đăng ký và khởi tạo một module tùy chỉnh chỉ trên instance cụ thể này.
Plugin
editor.use(plugin, options?)
Cài đặt một plugin chỉ trên instance này. Các nút của plugin được đăng ký ngay lập tức; nếu toolbar đã render, gọi editor.invoke('toolbar.rebuild').
editor.getPlugin<T>(name)
Trả về API công khai mà plugin.install() trả về, hoặc null.
editor.destroy()
Xóa toàn bộ DOM của editor, kích hoạt onDestroy, gọi plugin.uninstall() trên mọi plugin, và khôi phục phần tử gốc.
Callback & Sự kiện
Sự kiện có thể được đăng ký theo hai cách: qua callback tùy chọn (truyền vào create()) hoặc qua editor.on().
on() đều kích hoạt cho cùng một sự kiện. Dùng callback cho thiết lập một lần; dùng on() khi cần hủy đăng ký sau này.
// Option callback
const editor = AutumnNote.create('#editor', {
onChange(html) { /* ... */ },
onFocus(ctx) { /* ... */ },
onBlur(ctx) { /* ... */ },
onInit(ctx) { /* editor is ready */ },
onDestroy(ctx) { /* cleanup */ },
});
// Programmatic subscription
const unsub = editor.on('change', (html) => { /* ... */ });
editor.on('selectionChange', (ctx) => { /* cursor moved */ });
editor.on('focus', (ctx) => { /* ... */ });
editor.on('blur', (ctx) => { /* ... */ });
Cấu hình Toolbar
Tùy chọn toolbar là một mảng 2 chiều — mỗi mảng con là một nhóm nút (ngăn cách bằng dấu phân cách). Phần tử có thể là object ButtonDef import từ thư viện, hoặc tên chuỗi của nút đã đăng ký.
import AutumnNote, {
boldBtn, italicBtn, underlineBtn,
ulBtn, olBtn, linkBtn, imageBtn,
undoBtn, redoBtn,
defaultToolbar, // full default toolbar
} from 'autumnnote';
// Custom toolbar
const editor = AutumnNote.create('#editor', {
toolbar: [
[boldBtn, italicBtn, underlineBtn],
[ulBtn, olBtn],
[linkBtn, imageBtn],
[undoBtn, redoBtn],
],
});
Hoặc kết hợp object nút có tên với tên chuỗi (sau khi đăng ký nút tùy chỉnh):
AutumnNote.registerButton({
name: 'myButton',
icon: 'star', // SVG id or FontAwesome class name
tooltip: 'My Action',
action: (ctx) => { ctx.insertHTML('<mark>highlighted</mark>'); },
isActive: (ctx) => false,
});
const editor = AutumnNote.create('#editor', {
toolbar: [[boldBtn, italicBtn, 'myButton']],
});
Tất cả nút được export
| Export | Tooltip | Kiểu |
|---|---|---|
| boldBtn | Bold (Ctrl+B) | button |
| italicBtn | Italic (Ctrl+I) | button |
| underlineBtn | Underline (Ctrl+U) | button |
| strikeBtn | Strikethrough | button |
| inlineCodeBtn | Inline Code (Ctrl+`) | button |
| superscriptBtn | Superscript | button |
| subscriptBtn | Subscript | button |
| alignLeftBtn / alignCenterBtn / alignRightBtn / alignJustifyBtn | Alignment | button |
| ulBtn / olBtn / checklistBtn | Lists | button |
| indentBtn / outdentBtn | Indent / Outdent | button |
| undoBtn / redoBtn | Undo / Redo | button |
| hrBtn | Horizontal Rule | button |
| linkBtn / imageBtn / videoBtn | Insert dialogs | button |
| tableBtn | Insert Table | grid |
| emojiBtn / iconBtn | Emoji / FA Icon | button |
| foreColorBtn / backColorBtn | Text / Highlight Color | colorpicker |
| paragraphStyleBtn | Paragraph Style | select |
| fontFamilyBtn / fontSizeBtn / lineHeightBtn | Typography | select |
| removeFormatBtn / directionBtn | Utilities | button |
| codeviewBtn / fullscreenBtn | View | button |
| findBtn / findReplaceBtn / printBtn / shortcutsBtn | Tools | button |
| defaultToolbar | Full default toolbar array | array |
Có gì mới v1.8.0
Phiên bản 1.8.0 mở rộng API công khai với các phương thức Context mới, thêm định nghĩa nút UMD, tìm kiếm nguyên từ, giới hạn kích thước paste, kích thước tối thiểu khi thay đổi ảnh có thể cấu hình, cải tiến i18n, và nhiều hơn nữa.
Sắp xếp bảng, xuất CSV & đệm ô
Table Tooltip giờ có thêm ba thao tác quản lý dữ liệu mới:
- Sắp xếp Tăng dần / Giảm dần — sắp xếp tất cả các dòng theo cột đang chọn; giá trị số được so sánh dạng số, văn bản dùng so sánh theo locale; bố cục ô gộp được xử lý đúng.
- Xuất dạng CSV — tải toàn bộ bảng dưới dạng file
.csvUTF-8 (BOM) với escape dấu ngoặc kép đúng cho ô chứa dấu phẩy hoặc xuống dòng. - Đệm ô — mở popover kích thước để áp dụng đệm đồng nhất (px) cho tất cả ô đã chọn.
Nút Bật/tắt dòng tiêu đề cũng chuyển đổi dòng đầu tiên giữa <thead><th> (tiêu đề) và <tbody><td> (dữ liệu), tạo hoặc xóa bọc <thead> khi cần.
Tìm & Thay thế — Chế độ Regex
Một nút chuyển đổi .* mới trong panel Tìm & Thay thế kích hoạt tìm kiếm bằng regular expression JavaScript. Regex đã biên dịch được cache qua các lần gõ phím để tăng hiệu năng. Trường hợp sử dụng: tìm tất cả từ khớp một pattern, xác định địa chỉ email, thay thế số đã định dạng, v.v. Hoạt động cùng chế độ phân biệt hoa/thường; lỗi biên dịch regex được xử lý an toàn.
Số dòng khối mã
Code Tooltip giờ có thêm nút Bật/tắt số dòng. Khi bật, một CSS counter tạo ra một cột đánh số bên trái khối mã — không cần đếm bằng JavaScript, không thay đổi DOM nội dung. Trạng thái tự động đồng bộ khi chuyển giữa các khối mã.
Giao diện Tối-Tự động
Tùy chọn theme: 'auto' mới giúp editor tự động theo tùy chọn chế độ tối của hệ điều hành:
AutumnNote.create('#editor', { theme: 'auto' });
CSS @media (prefers-color-scheme: dark) kích hoạt bảng màu tối đầy đủ khi hệ điều hành ở chế độ tối; editor giữ giao diện sáng trong trường hợp ngược lại. theme: 'dark' và theme: 'light' vẫn buộc một giao diện cụ thể bất kể tùy chọn hệ điều hành.
API đếm Undo / Redo
Hai phương thức instance mới cho phép ứng dụng host truy vấn độ sâu stack undo/redo:
editor.getUndoCount(); // → number of available undo steps
editor.getRedoCount(); // → number of available redo steps
Hữu ích để vô hiệu hóa nút Undo/Redo trong UI tùy chỉnh, hoặc hiển thị badge đếm bước trong ứng dụng host.
Tìm kiếm @mention dựa trên Promise
Callback mention.onSearch giờ chấp nhận cả kiểu callback và Promise / async:
// Async / Promise style (new in 1.8.0)
AutumnNote.create('#editor', {
mention: {
onSearch: async (query) => {
const res = await fetch(`/api/users?q=${query}`);
return res.json(); // returns MentionItem[]
}
}
});
Nếu Promise reject, dropdown tự động đóng. Kiểu callback gốc vẫn được hỗ trợ đầy đủ.
Plugin API v1.4.1
Plugin API cho phép bạn đóng gói phần mở rộng editor — module tùy chỉnh, nút toolbar, và event handler — thành một object có thể tái sử dụng, cài đặt được. Plugin có thể phân phối dưới dạng package npm và cài đặt chỉ trong một dòng.
Descriptor plugin
Một plugin là một object đơn giản với các trường sau:
| Trường | Kiểu | Bắt buộc | Mô tả |
|---|---|---|---|
| name | string | ✓ | Định danh plugin duy nhất. Dùng làm key cho getPlugin(name) và hasPlugin(name). |
| version | string | — | Chuỗi phiên bản semantic — chỉ mang tính thông tin, không được runtime kiểm tra. |
| buttons | ToolbarItemDef[] | — | Định nghĩa nút đăng ký vào registry nút toàn cục ngay lập tức khi AutumnNote.use() được gọi — trước khi bất kỳ editor nào được tạo, nên chúng có sẵn theo tên chuỗi trong cấu hình toolbar. |
| install | (ctx, opts) → T | — | Được gọi sau khi tất cả 27 module có sẵn đã khởi tạo. Nhận Context và object tùy chọn truyền vào use(). Giá trị trả về trở thành API công khai của plugin, truy cập qua ctx.getPlugin(name). |
| uninstall | (ctx) → void | — | Được gọi khi instance editor bị hủy. Dùng để giải phóng timer, xóa DOM bên ngoài, hoặc ngắt kết nối trạng thái bên ngoài. |
const MyPlugin = {
name: 'my-plugin', // required
version: '1.0.0', // optional
buttons: [ // registered BEFORE create() — usable by name in toolbar
{
name: 'highlight',
icon: 'highlighter', // SVG id or FontAwesome class suffix
tooltip: 'Highlight selection',
action: (ctx) => ctx.invoke('editor.hiliteColor', '#fef08a'),
isActive: (ctx) => false,
isDisabled: (ctx) => ctx.isEmpty(),
},
],
install(context, options) {
// Full context API available here — all modules are ready
context.on('change', (html) => { /* react to content changes */ });
context.registerModule('myModule', MyModule);
return { getLimit: () => options.limit ?? 0 }; // public API
},
uninstall(context) {
// Clean up side-effects (timers, external DOM, subscriptions…)
},
};
Bên trong install(context, options)
Tham số context chính là object Context đầy đủ. Tất cả phương thức được mô tả trong phần Instance API đều khả dụng. Hữu ích nhất bên trong plugin:
Đăng ký sự kiện
// Subscribe — returns an unsubscribe function
const unsub = context.on('change', (html) => {
console.log('word count:', context.getWordCount());
});
// Available event names:
// 'change' — content changed (debounced ~400 ms)
// 'focus' — editor gained focus
// 'blur' — editor lost focus
// Unsubscribe in uninstall() to avoid leaks
uninstall(ctx) { unsub(); }
Gọi phương thức module có sẵn
context.invoke('module.method', ...args) gọi bất kỳ phương thức công khai nào trên module đã đăng ký. Các đường dẫn phổ biến:
| Đường dẫn | Mô tả |
|---|---|
| editor.bold / italic / underline / strikethrough | Bật/tắt định dạng văn bản tại con trỏ. |
| editor.inlineCode | Bật/tắt <code> nội dòng tại con trỏ. |
| editor.foreColor / hiliteColor | Áp dụng màu chữ / màu tô sáng. Truyền chuỗi màu làm tham số thứ 2: ctx.invoke('editor.foreColor', '#e11d48'). |
| editor.insertHTML | Chèn HTML tại vị trí con trỏ hiện tại. |
| editor.insertText | Chèn văn bản thuần tại vị trí con trỏ hiện tại. |
| editor.getHTML | Trả về chuỗi HTML hiện tại. |
| editor.setHTML | Thay thế toàn bộ nội dung. |
| editor.undo / redo | Duyệt qua lịch sử. |
| editor.focus | Focus vào vùng soạn thảo. |
| editor.afterCommand | Chụp ảnh lịch sử undo và kích hoạt onChange. Gọi hàm này sau bất kỳ thay đổi DOM trực tiếp nào. |
| toolbar.refresh | Đánh giá lại isActive / isDisabled trên mọi nút toolbar (debounce qua rAF). |
| toolbar.rebuild | Gỡ bỏ và render lại toàn bộ toolbar. Dùng sau khi đăng ký nút sau khi tạo. |
| linkDialog.show | Mở hộp thoại Chèn liên kết. |
| imageDialog.show | Mở hộp thoại Chèn ảnh. |
| findReplace.show | Mở hộp thoại Tìm kiếm. |
| fullscreen.toggle | Bật/tắt chế độ toàn màn hình. |
| codeview.toggle | Bật/tắt xem mã HTML. |
Đăng ký một module tùy chỉnh
Một module là một class với initialize() (bắt buộc) và destroy() (tùy chọn). Nó nhận Context trong constructor và có thể expose các phương thức gọi được qua context.invoke().
class WordBadgeModule {
constructor(context) {
this.context = context;
this._el = null;
this._unsub = null;
}
initialize() {
// Build UI
this._el = document.createElement('div');
this._el.className = 'word-badge';
this._el.textContent = '0 words';
this.context.layoutInfo.container.appendChild(this._el);
// React to content changes
this._unsub = this.context.on('change', () => this._update());
this._update();
return this;
}
// Public method — callable via ctx.invoke('wordBadge.getCount')
getCount() {
return this.context.getWordCount();
}
_update() {
const n = this.context.getWordCount();
this._el.textContent = `${n} word${n !== 1 ? 's' : ''}`;
}
destroy() {
this._unsub?.();
this._el?.remove();
this._el = null;
}
}
// Register inside install():
install(context) {
context.registerModule('wordBadge', WordBadgeModule);
// Now callable anywhere:
context.invoke('wordBadge.getCount'); // → number
}
Cài đặt
// ── Global (applies to every future create() call) ─────────────────────────
AutumnNote.use(MyPlugin, { limit: 500 });
AutumnNote.hasPlugin('my-plugin'); // → true
const editor = AutumnNote.create('#editor', {
toolbar: [[boldBtn, 'highlight']], // 'highlight' resolved from plugin.buttons
});
editor.getPlugin('my-plugin').getLimit(); // → 500
// ── Per-instance (this editor only) ────────────────────────────────────────
const editor2 = AutumnNote.create('#editor2');
editor2.use(MyPlugin, { limit: 200 });
editor2.invoke('toolbar.rebuild'); // surface new buttons in already-rendered toolbar
// ── Standalone button registration ─────────────────────────────────────────
AutumnNote.registerButton({
name: 'timestamp',
icon: 'clock',
tooltip: 'Insert current timestamp',
action: (ctx) => ctx.invoke('editor.insertText', new Date().toLocaleString()),
});
// Then reference by name in any toolbar config:
// toolbar: [[boldBtn, 'timestamp']]
AutumnNote.use(plugin) đăng ký plugin.buttons ngay lập tức (đồng bộ) để chúng có sẵn khi Toolbar được xây dựng trong create(). plugin.install() được gọi sau khi tất cả 27 module có sẵn đã sẵn sàng — an toàn để gọi ctx.invoke(), ctx.registerModule(), và bất kỳ phương thức nội dung nào.
Đa ngôn ngữ (i18n)
Truyền một mã ngôn ngữ vào tùy chọn lang. Các locale có sẵn: en (mặc định), vi, ja, zh, fr, de, es, ko.
const editor = AutumnNote.create('#editor', { lang: 'vi' });
// Override specific strings
const editor2 = AutumnNote.create('#editor2', {
lang: {
toolbar: { bold: 'Đậm (Ctrl+B)' },
findReplace: { noResults: 'Không tìm thấy' },
},
});
// Switch language at runtime (re-create editor)
const html = editor.getHTML();
editor.destroy();
const editor3 = AutumnNote.create('#editor', { lang: 'ja' });
editor3.setHTML(html);
TypeScript
AutumnNote đi kèm định nghĩa TypeScript có sẵn (types/index.d.ts). Không cần package @types.
import AutumnNote, {
Context,
AsnOptions,
AsnPlugin,
ButtonDef,
ToolbarItemDef,
AsnLocale,
} from 'autumnnote';
// Typed options
const options: AsnOptions = {
height: 300,
bubbleToolbar: true,
onChange(html: string) { /* ... */ },
};
// Typed plugin
const myPlugin: AsnPlugin<{ version: string }> = {
name: 'typed-plugin',
install(ctx: Context, opts) {
return { version: '1.0.0' };
},
};
AutumnNote.use(myPlugin);
const editor = AutumnNote.create('#editor', options);
// Cast plugin API to typed interface
const api = editor.getPlugin<{ version: string }>('typed-plugin');
console.log(api?.version); // '1.0.0'