@hufe921/canvas-editor 0.9.125 → 0.9.126

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,26 @@
1
+ ## [0.9.126](https://github.com/Hufe921/canvas-editor/compare/v0.9.125...v0.9.126) (2026-02-12)
2
+
3
+
4
+ ### Bug Fixes
5
+
6
+ * adjusted image rowFlex when converting HTML to elements #1354 ([3fe395e](https://github.com/Hufe921/canvas-editor/commit/3fe395e7c0e669d5d93bca673f9429faa20e2aeb)), closes [#1354](https://github.com/Hufe921/canvas-editor/issues/1354)
7
+ * cursor positioning when clicking control postfix #1353 ([ea650f6](https://github.com/Hufe921/canvas-editor/commit/ea650f6520b194d76458fbe33b88b01f901db4bc)), closes [#1353](https://github.com/Hufe921/canvas-editor/issues/1353)
8
+ * restore titleId when splitting/merging title #921 #1337 ([0b659ef](https://github.com/Hufe921/canvas-editor/commit/0b659ef9ff9d9562880dedba86e0c0540ea90c65)), closes [#921](https://github.com/Hufe921/canvas-editor/issues/921) [#1337](https://github.com/Hufe921/canvas-editor/issues/1337)
9
+
10
+
11
+ ### Chores
12
+
13
+ * add claude settings ([99de4e4](https://github.com/Hufe921/canvas-editor/commit/99de4e416e16b970b23d770319f278a9071ec4e7))
14
+ * update README.md ([afa05b2](https://github.com/Hufe921/canvas-editor/commit/afa05b2272d1c093ac02f948375e707291be5439))
15
+
16
+
17
+ ### Features
18
+
19
+ * add compute elements height and remaining page height api #1213 ([f5e80f9](https://github.com/Hufe921/canvas-editor/commit/f5e80f99f8505c57bf36f8b9c8e948a0b29cf6d8)), closes [#1213](https://github.com/Hufe921/canvas-editor/issues/1213)
20
+ * implement list number style inheritance with config option #727 ([0b99406](https://github.com/Hufe921/canvas-editor/commit/0b994068723c85bff504e04470ae82ee241b894e)), closes [#727](https://github.com/Hufe921/canvas-editor/issues/727)
21
+
22
+
23
+
1
24
  ## [0.9.125](https://github.com/Hufe921/canvas-editor/compare/v0.9.124...v0.9.125) (2026-02-07)
2
25
 
3
26
 
package/README.md CHANGED
@@ -1,5 +1,9 @@
1
1
  <h1 align="center">canvas-editor</h1>
2
2
 
3
+ <p align="center">
4
+ <a href="https://trendshift.io/repositories/8401" target="_blank"><img src="https://trendshift.io/api/badge/repositories/8401" alt="Hufe921%2Fcanvas-editor | Trendshift" style="width: 250px; height: 55px;" width="250" height="55"/></a>
5
+ </p>
6
+
3
7
  <p align="center">
4
8
  <a href="https://www.npmjs.com/package/@hufe921/canvas-editor" target="_blank"><img src="https://img.shields.io/npm/v/@hufe921/canvas-editor.svg?sanitize=true" alt="Version"></a>
5
9
  <a href="https://github.com/hufe921/canvas-editor/actions" target="_blank">
@@ -23,7 +23,7 @@ var __publicField = (obj, key, value) => {
23
23
  return value;
24
24
  };
25
25
  var index = "";
26
- const version = "0.9.125";
26
+ const version = "0.9.126";
27
27
  var MaxHeightRatio;
28
28
  (function(MaxHeightRatio2) {
29
29
  MaxHeightRatio2["HALF"] = "half";
@@ -4095,6 +4095,9 @@ var ListStyle;
4095
4095
  ListStyle2["DECIMAL"] = "decimal";
4096
4096
  ListStyle2["CHECKBOX"] = "checkbox";
4097
4097
  })(ListStyle || (ListStyle = {}));
4098
+ const defaultListOption = {
4099
+ inheritStyle: false
4100
+ };
4098
4101
  const ulStyleMapping = {
4099
4102
  [UlStyle.DISC]: "\u2022",
4100
4103
  [UlStyle.CIRCLE]: "\u25E6",
@@ -4480,6 +4483,7 @@ function mergeOption(options = {}) {
4480
4483
  const graffitiOptions = __spreadValues(__spreadValues({}, defaultGraffitiOption), options.graffiti);
4481
4484
  const labelOptions = __spreadValues(__spreadValues({}, defaultLabelOption), options.label);
4482
4485
  const imgCaptionOptions = __spreadValues(__spreadValues({}, defaultImgCaptionOption), options.imgCaption);
4486
+ const listOptions = __spreadValues(__spreadValues({}, defaultListOption), options.list);
4483
4487
  const modeRuleOption = {
4484
4488
  print: __spreadValues(__spreadValues({}, defaultModeRuleOption.print), (_a = options.modeRule) == null ? void 0 : _a.print),
4485
4489
  readonly: __spreadValues(__spreadValues({}, defaultModeRuleOption.readonly), (_b = options.modeRule) == null ? void 0 : _b.readonly),
@@ -4555,7 +4559,8 @@ function mergeOption(options = {}) {
4555
4559
  modeRule: modeRuleOption,
4556
4560
  graffiti: graffitiOptions,
4557
4561
  label: labelOptions,
4558
- imgCaption: imgCaptionOptions
4562
+ imgCaption: imgCaptionOptions,
4563
+ list: listOptions
4559
4564
  });
4560
4565
  }
4561
4566
  function unzipElementList(elementList) {
@@ -5743,7 +5748,8 @@ function getElementListByHTML(htmlText, options) {
5743
5748
  width,
5744
5749
  height,
5745
5750
  value: src,
5746
- type: ElementType.IMAGE
5751
+ type: ElementType.IMAGE,
5752
+ rowFlex: convertTextAlignToRowFlex(node.parentElement)
5747
5753
  });
5748
5754
  }
5749
5755
  } else if (node.nodeName === "VIDEO") {
@@ -7238,6 +7244,7 @@ function backspaceHideElement(host) {
7238
7244
  }
7239
7245
  }
7240
7246
  function backspace(evt, host) {
7247
+ var _a;
7241
7248
  const draw = host.getDraw();
7242
7249
  if (draw.isReadonly())
7243
7250
  return;
@@ -7292,12 +7299,23 @@ function backspace(evt, host) {
7292
7299
  if (isCollapsed && startElement.rowFlex && startElement.value === ZERO) {
7293
7300
  const rowFlexElementList = rangeManager.getRangeRowElementList();
7294
7301
  if (rowFlexElementList) {
7295
- const preElement = elementList[startIndex - 1];
7302
+ const preElement2 = elementList[startIndex - 1];
7296
7303
  rowFlexElementList.forEach((element) => {
7297
- element.rowFlex = preElement == null ? void 0 : preElement.rowFlex;
7304
+ element.rowFlex = preElement2 == null ? void 0 : preElement2.rowFlex;
7298
7305
  });
7299
7306
  }
7300
7307
  }
7308
+ const preElement = startElement.value === ZERO ? elementList[startIndex - 1] : startElement;
7309
+ const nextElement = elementList[endIndex + 1];
7310
+ if ((preElement == null ? void 0 : preElement.titleId) && (nextElement == null ? void 0 : nextElement.titleId) && preElement.level === nextElement.level && preElement.titleId !== nextElement.titleId) {
7311
+ const preTitleId = preElement.titleId;
7312
+ const nextTitleId = nextElement.titleId;
7313
+ let nextIndex = endIndex + 1;
7314
+ while (nextIndex < elementList.length && ((_a = elementList[nextIndex]) == null ? void 0 : _a.titleId) === nextTitleId) {
7315
+ elementList[nextIndex].titleId = preTitleId;
7316
+ nextIndex++;
7317
+ }
7318
+ }
7301
7319
  if (!isCollapsed) {
7302
7320
  draw.spliceElementList(elementList, startIndex + 1, endIndex - startIndex);
7303
7321
  } else {
@@ -7420,7 +7438,7 @@ function del(evt, host) {
7420
7438
  }
7421
7439
  }
7422
7440
  function enter(evt, host) {
7423
- var _a, _b, _c, _d, _e;
7441
+ var _a, _b, _c, _d, _e, _f, _g;
7424
7442
  const draw = host.getDraw();
7425
7443
  if (draw.isReadonly())
7426
7444
  return;
@@ -7478,6 +7496,14 @@ function enter(evt, host) {
7478
7496
  const { index: index2 } = cursorPosition;
7479
7497
  if (isCollapsed) {
7480
7498
  draw.spliceElementList(elementList, index2 + 1, 0, [enterText]);
7499
+ if (endElement.titleId && ((_f = elementList[index2 + 2]) == null ? void 0 : _f.titleId) === endElement.titleId) {
7500
+ const newTitleId = getUUID();
7501
+ let nextIndex = index2 + 2;
7502
+ while (nextIndex < elementList.length && ((_g = elementList[nextIndex]) == null ? void 0 : _g.titleId) === endElement.titleId) {
7503
+ elementList[nextIndex].titleId = newTitleId;
7504
+ nextIndex++;
7505
+ }
7506
+ }
7481
7507
  } else {
7482
7508
  draw.spliceElementList(elementList, startIndex + 1, endIndex - startIndex, [enterText]);
7483
7509
  }
@@ -14609,6 +14635,12 @@ class Control {
14609
14635
  newElement: elementList[startIndex - 1]
14610
14636
  };
14611
14637
  }
14638
+ if (startIndex === elementList.length - 1) {
14639
+ return {
14640
+ newIndex: startIndex,
14641
+ newElement: elementList[startIndex]
14642
+ };
14643
+ }
14612
14644
  startIndex++;
14613
14645
  }
14614
14646
  } else if (element.controlComponent === ControlComponent.PREFIX || element.controlComponent === ControlComponent.PRE_TEXT) {
@@ -17285,6 +17317,26 @@ class ListParticle {
17285
17317
  }
17286
17318
  return listStyleMap;
17287
17319
  }
17320
+ findStyledElement(elementList) {
17321
+ let styleElement = elementList[0];
17322
+ for (let i = 1; i < elementList.length; i++) {
17323
+ const element = elementList[i];
17324
+ if (element.font || element.size || element.bold || element.italic) {
17325
+ styleElement = element;
17326
+ break;
17327
+ }
17328
+ }
17329
+ return styleElement;
17330
+ }
17331
+ getListFontStyle(elementList, scale) {
17332
+ if (this.options.list.inheritStyle) {
17333
+ const styleElement = this.findStyledElement(elementList);
17334
+ return this.draw.getElementFont(styleElement, scale);
17335
+ } else {
17336
+ const { defaultFont, defaultSize } = this.options;
17337
+ return `${defaultSize * scale}px ${defaultFont}`;
17338
+ }
17339
+ }
17288
17340
  getListStyleWidth(ctx, listElementList) {
17289
17341
  const { scale, checkbox } = this.options;
17290
17342
  const startElement = listElementList[0];
@@ -17302,8 +17354,11 @@ class ListParticle {
17302
17354
  }, 0);
17303
17355
  if (!count)
17304
17356
  return 0;
17357
+ ctx.save();
17358
+ ctx.font = this.getListFontStyle(listElementList, scale);
17305
17359
  const text = `${this.MEASURE_BASE_TEXT.repeat(String(count).length)}${KeyMap.PERIOD}`;
17306
17360
  const textMetrics = ctx.measureText(text);
17361
+ ctx.restore();
17307
17362
  return Math.ceil((textMetrics.width + this.LIST_GAP) * scale);
17308
17363
  }
17309
17364
  drawListStyle(ctx, row, position) {
@@ -17313,7 +17368,7 @@ class ListParticle {
17313
17368
  if (startElement.value !== ZERO || startElement.listWrap)
17314
17369
  return;
17315
17370
  let tabWidth = 0;
17316
- const { defaultTabWidth, scale, defaultFont, defaultSize } = this.options;
17371
+ const { defaultTabWidth, scale } = this.options;
17317
17372
  for (let i = 1; i < elementList.length; i++) {
17318
17373
  const element = elementList[i];
17319
17374
  if ((element == null ? void 0 : element.type) !== ElementType.TAB)
@@ -17353,7 +17408,7 @@ class ListParticle {
17353
17408
  if (!text)
17354
17409
  return;
17355
17410
  ctx.save();
17356
- ctx.font = `${defaultSize * scale}px ${defaultFont}`;
17411
+ ctx.font = this.getListFontStyle(elementList, scale);
17357
17412
  ctx.fillText(text, x, y);
17358
17413
  ctx.restore();
17359
17414
  }
@@ -21238,6 +21293,7 @@ class Command {
21238
21293
  __publicField(this, "executeUpdateOptions");
21239
21294
  __publicField(this, "executeInsertTitle");
21240
21295
  __publicField(this, "executeFocus");
21296
+ __publicField(this, "executeComputeElementListHeight");
21241
21297
  __publicField(this, "getCatalog");
21242
21298
  __publicField(this, "getImage");
21243
21299
  __publicField(this, "getOptions");
@@ -21248,6 +21304,7 @@ class Command {
21248
21304
  __publicField(this, "getText");
21249
21305
  __publicField(this, "getWordCount");
21250
21306
  __publicField(this, "getCursorPosition");
21307
+ __publicField(this, "getRemainingContentHeight");
21251
21308
  __publicField(this, "getRange");
21252
21309
  __publicField(this, "getRangeText");
21253
21310
  __publicField(this, "getRangeContext");
@@ -21370,6 +21427,7 @@ class Command {
21370
21427
  this.executeUpdateOptions = adapt.updateOptions.bind(adapt);
21371
21428
  this.executeInsertTitle = adapt.insertTitle.bind(adapt);
21372
21429
  this.executeFocus = adapt.focus.bind(adapt);
21430
+ this.executeComputeElementListHeight = adapt.computeElementListHeight.bind(adapt);
21373
21431
  this.getImage = adapt.getImage.bind(adapt);
21374
21432
  this.getOptions = adapt.getOptions.bind(adapt);
21375
21433
  this.getValue = adapt.getValue.bind(adapt);
@@ -21378,6 +21436,7 @@ class Command {
21378
21436
  this.getText = adapt.getText.bind(adapt);
21379
21437
  this.getWordCount = adapt.getWordCount.bind(adapt);
21380
21438
  this.getCursorPosition = adapt.getCursorPosition.bind(adapt);
21439
+ this.getRemainingContentHeight = adapt.getRemainingContentHeight.bind(adapt);
21381
21440
  this.getRange = adapt.getRange.bind(adapt);
21382
21441
  this.getRangeText = adapt.getRangeText.bind(adapt);
21383
21442
  this.getRangeContext = adapt.getRangeContext.bind(adapt);
@@ -22707,6 +22766,33 @@ class CommandAdapt {
22707
22766
  getCursorPosition() {
22708
22767
  return this.position.getCursorPosition();
22709
22768
  }
22769
+ getRemainingContentHeight() {
22770
+ if (!this.draw.getIsPagingMode())
22771
+ return 0;
22772
+ const pageRowList = this.draw.getPageRowList();
22773
+ const lastPageIndex = pageRowList.length - 1;
22774
+ const rowList = pageRowList[lastPageIndex] || [];
22775
+ const usedHeight = rowList.reduce((pre, cur) => pre + cur.height + (cur.offsetY || 0), 0);
22776
+ const height = this.draw.getHeight();
22777
+ const mainOuterHeight = this.draw.getMainOuterHeight();
22778
+ const remaining = height - (mainOuterHeight + usedHeight);
22779
+ return remaining > 0 ? remaining : 0;
22780
+ }
22781
+ computeElementListHeight(elementList) {
22782
+ if (!elementList.length)
22783
+ return 0;
22784
+ const innerWidth = this.draw.getInnerWidth();
22785
+ if (innerWidth <= 0)
22786
+ return 0;
22787
+ const targetElementList = deepClone(elementList);
22788
+ const surroundElementList = pickSurroundElementList(targetElementList);
22789
+ const rowList = this.draw.computeRowList({
22790
+ innerWidth,
22791
+ elementList: targetElementList,
22792
+ surroundElementList
22793
+ });
22794
+ return rowList.reduce((pre, cur) => pre + cur.height + (cur.offsetY || 0), 0);
22795
+ }
22710
22796
  getRange() {
22711
22797
  return deepClone(this.range.getRange());
22712
22798
  }