@phuong-tran-redoc/document-engine-core 0.0.36 → 0.0.41
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/src/__tests__/helpers/editor-factory.d.ts +13 -0
- package/src/__tests__/helpers/editor-factory.js +25 -0
- package/src/extensions/ordered-list.extension.js +10 -1
- package/src/extensions/table-style.extension.d.ts +0 -1
- package/src/extensions/table-style.extension.js +1 -1
- package/src/types/ordered-list.type.d.ts +1 -1
- package/src/types/ordered-list.type.js +1 -0
- package/src/utils/table.util.js +28 -23
package/package.json
CHANGED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { Editor } from '@tiptap/core';
|
|
2
|
+
import type { Extensions } from '@tiptap/core';
|
|
3
|
+
/**
|
|
4
|
+
* Create a test editor instance with minimal required extensions
|
|
5
|
+
* @param extensions Additional extensions to include
|
|
6
|
+
* @param content Initial content (HTML string or JSON)
|
|
7
|
+
* @returns Editor instance
|
|
8
|
+
*/
|
|
9
|
+
export declare function createTestEditor(extensions?: Extensions, content?: string | Record<string, unknown>): Editor;
|
|
10
|
+
/**
|
|
11
|
+
* Destroy editor and cleanup
|
|
12
|
+
*/
|
|
13
|
+
export declare function destroyEditor(editor: Editor): void;
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { Editor } from '@tiptap/core';
|
|
2
|
+
import { Document } from '@tiptap/extension-document';
|
|
3
|
+
import { Paragraph } from '@tiptap/extension-paragraph';
|
|
4
|
+
import { Text } from '@tiptap/extension-text';
|
|
5
|
+
/**
|
|
6
|
+
* Create a test editor instance with minimal required extensions
|
|
7
|
+
* @param extensions Additional extensions to include
|
|
8
|
+
* @param content Initial content (HTML string or JSON)
|
|
9
|
+
* @returns Editor instance
|
|
10
|
+
*/ export function createTestEditor(extensions = [], content = '') {
|
|
11
|
+
return new Editor({
|
|
12
|
+
extensions: [
|
|
13
|
+
Document,
|
|
14
|
+
Paragraph,
|
|
15
|
+
Text,
|
|
16
|
+
...extensions
|
|
17
|
+
],
|
|
18
|
+
content
|
|
19
|
+
});
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Destroy editor and cleanup
|
|
23
|
+
*/ export function destroyEditor(editor) {
|
|
24
|
+
editor.destroy();
|
|
25
|
+
}
|
|
@@ -12,7 +12,16 @@ export const CustomOrderedList = OrderedList.extend({
|
|
|
12
12
|
...this.parent?.(),
|
|
13
13
|
'data-list-style-type': {
|
|
14
14
|
default: this.options.listStyleType,
|
|
15
|
-
parseHTML: (element)=>
|
|
15
|
+
parseHTML: (element)=>{
|
|
16
|
+
// Priority 1: Parse from data-list-style-type attribute (our format)
|
|
17
|
+
const dataAttr = element.getAttribute('data-list-style-type');
|
|
18
|
+
if (dataAttr) return dataAttr;
|
|
19
|
+
// Priority 2: Parse from CSS list-style-type property (other editors' format)
|
|
20
|
+
const styleAttr = element.style.listStyleType;
|
|
21
|
+
if (styleAttr) return styleAttr;
|
|
22
|
+
// Default fallback
|
|
23
|
+
return this.options.listStyleType;
|
|
24
|
+
},
|
|
16
25
|
renderHTML: (attributes)=>{
|
|
17
26
|
const styleType = attributes['data-list-style-type'];
|
|
18
27
|
if (!styleType || styleType === 'decimal') return {
|
|
@@ -2,10 +2,10 @@ import { Extension } from '@tiptap/core';
|
|
|
2
2
|
import { Table, TableCell, TableHeader, TableRow } from '@tiptap/extension-table';
|
|
3
3
|
import { TextSelection } from '@tiptap/pm/state';
|
|
4
4
|
import { addColumnAfter, addColumnBefore, deleteColumn, selectionCell, TableMap } from '@tiptap/pm/tables';
|
|
5
|
+
import { MIN_NEW_COL_WIDTH } from '../constants/table.constant';
|
|
5
6
|
import { getCursorCellInfo } from '../utils';
|
|
6
7
|
import { createTableNodeView } from '../views';
|
|
7
8
|
import { PercentageColumnResizing } from './table-resizing.extension';
|
|
8
|
-
export const MIN_NEW_COL_WIDTH = 5.0;
|
|
9
9
|
/**
|
|
10
10
|
* Calculate new column widths when adding a column, ensuring no column goes below MIN_NEW_COL_WIDTH
|
|
11
11
|
* @param oldColWidths - Array of current column widths
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export type ListStyleType = 'decimal' | 'lower-alpha-dot' | 'lower-alpha-parens' | 'lower-roman-parens';
|
|
1
|
+
export type ListStyleType = 'decimal' | 'lower-alpha' | 'upper-alpha' | 'lower-roman' | 'upper-roman' | 'lower-alpha-dot' | 'lower-alpha-parens' | 'lower-roman-parens' | 'decimal-leading-zero' | 'lower-latin' | 'upper-latin';
|
package/src/utils/table.util.js
CHANGED
|
@@ -2,31 +2,36 @@ import { CellSelection, findTable, selectionCell, TableMap } from '@tiptap/pm/ta
|
|
|
2
2
|
import { isEqual } from 'lodash-es';
|
|
3
3
|
export function getCursorCellInfo(state) {
|
|
4
4
|
// 1. Dùng selectionCell để tìm vị trí bắt đầu của ô chứa con trỏ
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
5
|
+
try {
|
|
6
|
+
const cellInfo = selectionCell(state);
|
|
7
|
+
// Nếu không tìm thấy (con trỏ không nằm trong ô nào), trả về null
|
|
8
|
+
if (!cellInfo) return null;
|
|
9
|
+
// cellInfo.$pos là một ResolvedPos trỏ tới vị trí bắt đầu của ô
|
|
10
|
+
const table = findTable(cellInfo);
|
|
11
|
+
if (!table) return null;
|
|
12
|
+
const map = TableMap.get(table.node);
|
|
13
|
+
// 2. Lấy vị trí tương đối của ô so với bảng
|
|
14
|
+
const cellOffset = cellInfo.pos - table.start;
|
|
15
|
+
// 3. Tìm chỉ số (index) của ô này trong "bản đồ" của bảng
|
|
16
|
+
const cellIndex = map.map.indexOf(cellOffset);
|
|
17
|
+
if (cellIndex === -1) {
|
|
18
|
+
return null;
|
|
19
|
+
}
|
|
20
|
+
// 4. Từ chỉ số, tính ra rowIndex và colIndex
|
|
21
|
+
const rowIndex = Math.floor(cellIndex / map.width);
|
|
22
|
+
const colIndex = cellIndex % map.width;
|
|
23
|
+
return {
|
|
24
|
+
rowIndex,
|
|
25
|
+
colIndex,
|
|
26
|
+
cellIndex,
|
|
27
|
+
tableStart: table.start,
|
|
28
|
+
tableNode: table.node,
|
|
29
|
+
map
|
|
30
|
+
};
|
|
31
|
+
} catch {
|
|
32
|
+
// selectionCell throws RangeError when cursor is not in a table
|
|
17
33
|
return null;
|
|
18
34
|
}
|
|
19
|
-
// 4. Từ chỉ số, tính ra rowIndex và colIndex
|
|
20
|
-
const rowIndex = Math.floor(cellIndex / map.width);
|
|
21
|
-
const colIndex = cellIndex % map.width;
|
|
22
|
-
return {
|
|
23
|
-
rowIndex,
|
|
24
|
-
colIndex,
|
|
25
|
-
cellIndex,
|
|
26
|
-
tableStart: table.start,
|
|
27
|
-
tableNode: table.node,
|
|
28
|
-
map
|
|
29
|
-
};
|
|
30
35
|
}
|
|
31
36
|
export function getSelectedCells(state) {
|
|
32
37
|
const { selection } = state;
|