@hufe921/canvas-editor 0.9.132 → 0.9.133

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/CHANGELOG.md CHANGED
@@ -1,3 +1,31 @@
1
+ ## [0.9.133](https://github.com/Hufe921/canvas-editor/compare/v0.9.132...v0.9.133) (2026-05-05)
2
+
3
+
4
+ ### Bug Fixes
5
+
6
+ * prevent prototype pollution in mergeObject #1405 ([e18abe4](https://github.com/Hufe921/canvas-editor/commit/e18abe497ea3ef37aff8e0611879e53fac069272)), closes [#1405](https://github.com/Hufe921/canvas-editor/issues/1405)
7
+
8
+
9
+ ### Chores
10
+
11
+ * migrate package manager from yarn to pnpm ([8a03995](https://github.com/Hufe921/canvas-editor/commit/8a039952151c7590292e9961329f94ce6851ad2b))
12
+ * update release script ([06172a3](https://github.com/Hufe921/canvas-editor/commit/06172a366f3ed875c3f30e66c54f89769683070a))
13
+ * upgrade dependency version #1407 ([1125ae4](https://github.com/Hufe921/canvas-editor/commit/1125ae448479f0feb56174d85fe4996a61d65629)), closes [#1407](https://github.com/Hufe921/canvas-editor/issues/1407)
14
+
15
+
16
+ ### Features
17
+
18
+ * allow setGroup and deleteGroup in readonly/form mode #1406 ([bd6e903](https://github.com/Hufe921/canvas-editor/commit/bd6e9039e76114c3af2c29b37481462e52244633)), closes [#1406](https://github.com/Hufe921/canvas-editor/issues/1406)
19
+ * auto-generate colgroup for table when not provided #1404 ([636a786](https://github.com/Hufe921/canvas-editor/commit/636a7868fbace75d35cff2e18c01d9caed01d30c)), closes [#1404](https://github.com/Hufe921/canvas-editor/issues/1404)
20
+
21
+
22
+ ### Tests
23
+
24
+ * add unit tests for core modules ([a12c679](https://github.com/Hufe921/canvas-editor/commit/a12c67988b2eea07f4ec926038f120bb85c4f746))
25
+ * improve test coverage with new test cases ([10357f6](https://github.com/Hufe921/canvas-editor/commit/10357f6b6f92e561b043061fc0b6d159f155c1ba))
26
+
27
+
28
+
1
29
  ## [0.9.132](https://github.com/Hufe921/canvas-editor/compare/v0.9.131...v0.9.132) (2026-04-24)
2
30
 
3
31
 
package/README.md CHANGED
@@ -93,7 +93,7 @@ new Editor(document.querySelector('.canvas-editor'), {
93
93
 
94
94
  ## Install
95
95
 
96
- `yarn`
96
+ `pnpm install`
97
97
 
98
98
  ## Dev
99
99
 
@@ -0,0 +1 @@
1
+ {"version":3,"file":"catalog-Cno2frQt.js","names":[],"sources":["../../src/editor/core/worker/works/catalog.ts"],"sourcesContent":["import { ICatalog, ICatalogItem } from '../../../interface/Catalog'\nimport { IElement, IElementPosition } from '../../../interface/Element'\n\ninterface IGetCatalogPayload {\n elementList: IElement[]\n positionList: IElementPosition[]\n}\n\ntype ICatalogElement = IElement & {\n pageNo: number\n}\n\nenum ElementType {\n TEXT = 'text',\n IMAGE = 'image',\n TABLE = 'table',\n HYPERLINK = 'hyperlink',\n SUPERSCRIPT = 'superscript',\n SUBSCRIPT = 'subscript',\n SEPARATOR = 'separator',\n PAGE_BREAK = 'pageBreak',\n CONTROL = 'control',\n CHECKBOX = 'checkbox',\n RADIO = 'radio',\n LATEX = 'latex',\n TAB = 'tab',\n DATE = 'date',\n BLOCK = 'block',\n TITLE = 'title',\n AREA = 'area',\n LIST = 'list',\n LABEL = 'label'\n}\n\nenum TitleLevel {\n FIRST = 'first',\n SECOND = 'second',\n THIRD = 'third',\n FOURTH = 'fourth',\n FIFTH = 'fifth',\n SIXTH = 'sixth'\n}\n\nconst titleOrderNumberMapping: Record<TitleLevel, number> = {\n [TitleLevel.FIRST]: 1,\n [TitleLevel.SECOND]: 2,\n [TitleLevel.THIRD]: 3,\n [TitleLevel.FOURTH]: 4,\n [TitleLevel.FIFTH]: 5,\n [TitleLevel.SIXTH]: 6\n}\n\nconst TEXTLIKE_ELEMENT_TYPE: ElementType[] = [\n ElementType.TEXT,\n ElementType.HYPERLINK,\n ElementType.SUBSCRIPT,\n ElementType.SUPERSCRIPT,\n ElementType.CONTROL,\n ElementType.DATE,\n ElementType.LABEL\n]\n\nconst ZERO = '\\u200B'\n\nfunction isTextLikeElement(element: IElement): boolean {\n return !element.type || TEXTLIKE_ELEMENT_TYPE.includes(element.type)\n}\n\nfunction getCatalog(payload: IGetCatalogPayload): ICatalog | null {\n const { elementList, positionList } = payload\n // 筛选标题\n const titleElementList: ICatalogElement[] = []\n let t = 0\n while (t < elementList.length) {\n const element = elementList[t]\n const getElementInfo = (\n element: IElement,\n elementList: IElement[],\n position: number\n ) => {\n const titleId = element.titleId\n const level = element.level\n const titleElement: ICatalogElement = {\n type: ElementType.TITLE,\n value: '',\n level,\n titleId,\n pageNo: positionList[t].pageNo\n }\n const valueList: IElement[] = []\n while (position < elementList.length) {\n const titleE = elementList[position]\n if (titleId !== titleE.titleId) {\n position--\n break\n }\n valueList.push(titleE)\n position++\n }\n titleElement.value = valueList\n .filter(el => isTextLikeElement(el))\n .map(el => el.value)\n .join('')\n .replace(new RegExp(ZERO, 'g'), '')\n return { position, titleElement }\n }\n if (element.titleId) {\n const { position, titleElement } = getElementInfo(element, elementList, t)\n t = position\n titleElementList.push(titleElement)\n }\n if (element.type === ElementType.TABLE) {\n const trList = element.trList!\n for (let r = 0; r < trList.length; r++) {\n const tr = trList[r]\n for (let d = 0; d < tr.tdList.length; d++) {\n const td = tr.tdList[d]\n const value = td.value\n if (value.length > 1) {\n let index = 1\n while (index < value.length) {\n if (value[index]?.titleId) {\n const { titleElement, position } = getElementInfo(\n value[index],\n value,\n index\n )\n titleElementList.push(titleElement)\n index = position\n }\n index++\n }\n }\n }\n }\n }\n t++\n }\n if (!titleElementList.length) return null\n // 查找到比最新元素大的标题时终止\n const recursiveInsert = (\n title: ICatalogElement,\n catalogItem: ICatalogItem\n ) => {\n const subCatalogItem =\n catalogItem.subCatalog[catalogItem.subCatalog.length - 1]\n const catalogItemLevel = titleOrderNumberMapping[subCatalogItem?.level]\n const titleLevel = titleOrderNumberMapping[title.level!]\n if (subCatalogItem && titleLevel > catalogItemLevel) {\n recursiveInsert(title, subCatalogItem)\n } else {\n catalogItem.subCatalog.push({\n id: title.titleId!,\n name: title.value,\n level: title.level!,\n pageNo: title.pageNo,\n subCatalog: []\n })\n }\n }\n // 循环标题组\n // 如果当前列表级别小于标题组最新标题级别:则递归查找最小级别并追加\n // 如果大于:则直接追加至当前标题组\n const catalog: ICatalog = []\n for (let e = 0; e < titleElementList.length; e++) {\n const title = titleElementList[e]\n const catalogItem = catalog[catalog.length - 1]\n const catalogItemLevel = titleOrderNumberMapping[catalogItem?.level]\n const titleLevel = titleOrderNumberMapping[title.level!]\n if (catalogItem && titleLevel > catalogItemLevel) {\n recursiveInsert(title, catalogItem)\n } else {\n catalog.push({\n id: title.titleId!,\n name: title.value,\n level: title.level!,\n pageNo: title.pageNo,\n subCatalog: []\n })\n }\n }\n return catalog\n}\n\nonmessage = evt => {\n const payload = <IGetCatalogPayload>evt.data\n const catalog = getCatalog(payload)\n postMessage(catalog)\n}\n"],"mappings":"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"}
@@ -0,0 +1 @@
1
+ {"version":3,"file":"group-Bz5rW3In.js","names":[],"sources":["../../src/editor/core/worker/works/group.ts"],"sourcesContent":["import { IElement } from '../../../interface/Element'\n\nenum ElementType {\n TABLE = 'table'\n}\n\nfunction getGroupIds(elementList: IElement[]): string[] {\n const groupIds: string[] = []\n for (const element of elementList) {\n if (element.type === ElementType.TABLE) {\n const trList = element.trList!\n for (let r = 0; r < trList.length; r++) {\n const tr = trList[r]\n for (let d = 0; d < tr.tdList.length; d++) {\n const td = tr.tdList[d]\n groupIds.push(...getGroupIds(td.value))\n }\n }\n }\n if (!element.groupIds) continue\n for (const groupId of element.groupIds) {\n if (!groupIds.includes(groupId)) {\n groupIds.push(groupId)\n }\n }\n }\n return groupIds\n}\n\nonmessage = evt => {\n const elementList = <IElement[]>evt.data\n const groupIds = getGroupIds(elementList)\n postMessage(groupIds)\n}\n"],"mappings":"YAEA,IAAK,EAAL,SAAA,EAAA,OACE,GAAA,MAAQ,WADL,GAAA,EAAA,CAEJ,CAED,SAAS,EAAY,EAAmC,CACtD,IAAM,EAAqB,EAAE,CAC7B,IAAK,IAAM,KAAW,EAAa,CACjC,GAAI,EAAQ,OAAS,EAAY,MAAO,CACtC,IAAM,EAAS,EAAQ,OACvB,IAAK,IAAI,EAAI,EAAG,EAAI,EAAO,OAAQ,IAAK,CACtC,IAAM,EAAK,EAAO,GAClB,IAAK,IAAI,EAAI,EAAG,EAAI,EAAG,OAAO,OAAQ,IAAK,CACzC,IAAM,EAAK,EAAG,OAAO,GACrB,EAAS,KAAK,GAAG,EAAY,EAAG,MAAM,CAAC,GAIxC,KAAQ,SACb,IAAK,IAAM,KAAW,EAAQ,SACvB,EAAS,SAAS,EAAQ,EAC7B,EAAS,KAAK,EAAQ,CAI5B,OAAO,EAGT,UAAY,GAAO,CACjB,IAAM,EAA0B,EAAI,KAC9B,EAAW,EAAY,EAAY,CACzC,YAAY,EAAS"}