@hufe921/canvas-editor 0.9.54 → 0.9.55

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,23 @@
1
+ ## [0.9.55](https://github.com/Hufe921/canvas-editor/compare/v0.9.54...v0.9.55) (2023-11-10)
2
+
3
+
4
+ ### Bug Fixes
5
+
6
+ * break after pasting HTML #318 ([80f6531](https://github.com/Hufe921/canvas-editor/commit/80f6531b96e22b434cd10b4441dba86c8944f99b)), closes [#318](https://github.com/Hufe921/canvas-editor/issues/318)
7
+ * delete table row boundary error #313 ([8f8bc04](https://github.com/Hufe921/canvas-editor/commit/8f8bc046db60a7c66c3b17e61b1f9f5a5c731f58)), closes [#313](https://github.com/Hufe921/canvas-editor/issues/313)
8
+ * reset event ability after delete element #314 ([c6483a4](https://github.com/Hufe921/canvas-editor/commit/c6483a4da68881490cc25c52cafcf96386d9a0a6)), closes [#314](https://github.com/Hufe921/canvas-editor/issues/314)
9
+ * shrink control range boundary error #305 ([a9fc226](https://github.com/Hufe921/canvas-editor/commit/a9fc226a39c3ef78d217fe7435b4b463c5879eac)), closes [#305](https://github.com/Hufe921/canvas-editor/issues/305)
10
+
11
+
12
+ ### Features
13
+
14
+ * add pageScaleChange eventbus #321 ([c697586](https://github.com/Hufe921/canvas-editor/commit/c69758686de22328ac84138ed2c2aa9a0668ed78)), closes [#321](https://github.com/Hufe921/canvas-editor/issues/321)
15
+ * add scrollContainerSelection option #320 ([192113e](https://github.com/Hufe921/canvas-editor/commit/192113e271b02cf3e4a462343a7b3d5604b90b23)), closes [#320](https://github.com/Hufe921/canvas-editor/issues/320)
16
+ * collapsed selection rect information ([7c32f95](https://github.com/Hufe921/canvas-editor/commit/7c32f9572f4d29fbf2f5d6d3f775c5dbe2d0ba8b))
17
+ * support for paste richtext data in contextmenu ([8989831](https://github.com/Hufe921/canvas-editor/commit/8989831474f637fe52133abc85d1ed2dc41f6354))
18
+
19
+
20
+
1
21
  ## [0.9.54](https://github.com/Hufe921/canvas-editor/compare/v0.9.53...v0.9.54) (2023-11-03)
2
22
 
3
23
 
@@ -23,7 +23,7 @@ var __publicField = (obj, key, value) => {
23
23
  return value;
24
24
  };
25
25
  var index = "";
26
- const version = "0.9.54";
26
+ const version = "0.9.55";
27
27
  var MaxHeightRatio;
28
28
  (function(MaxHeightRatio2) {
29
29
  MaxHeightRatio2["HALF"] = "half";
@@ -4516,6 +4516,168 @@ ${listIndex + 1}.${buildText(listElementList)}${isLast ? `
4516
4516
  }
4517
4517
  return buildText(zipElementList(elementList));
4518
4518
  }
4519
+ function pastHTML(host, htmlText) {
4520
+ const draw = host.getDraw();
4521
+ const isReadonly = draw.isReadonly();
4522
+ if (isReadonly)
4523
+ return;
4524
+ const rangeManager = draw.getRange();
4525
+ const { startIndex } = rangeManager.getRange();
4526
+ const elementList = draw.getElementList();
4527
+ const pasteElementList = getElementListByHTML(htmlText, {
4528
+ innerWidth: draw.getOriginalInnerWidth()
4529
+ });
4530
+ if (~startIndex && !rangeManager.getIsSelectAll()) {
4531
+ const anchorElement = elementList[startIndex];
4532
+ if ((anchorElement == null ? void 0 : anchorElement.titleId) || (anchorElement == null ? void 0 : anchorElement.listId)) {
4533
+ let start = 0;
4534
+ while (start < pasteElementList.length) {
4535
+ const pasteElement = pasteElementList[start];
4536
+ if (anchorElement.titleId && /^\n/.test(pasteElement.value)) {
4537
+ break;
4538
+ }
4539
+ if (VIRTUAL_ELEMENT_TYPE.includes(pasteElement.type)) {
4540
+ pasteElementList.splice(start, 1);
4541
+ if (pasteElement.valueList) {
4542
+ for (let v = 0; v < pasteElement.valueList.length; v++) {
4543
+ const element = pasteElement.valueList[v];
4544
+ if (element.value === ZERO || element.value === "\n") {
4545
+ continue;
4546
+ }
4547
+ pasteElementList.splice(start, 0, element);
4548
+ start++;
4549
+ }
4550
+ }
4551
+ start--;
4552
+ }
4553
+ start++;
4554
+ }
4555
+ }
4556
+ formatElementContext(elementList, pasteElementList, startIndex, {
4557
+ isBreakWhenWrap: true
4558
+ });
4559
+ }
4560
+ draw.insertElementList(pasteElementList);
4561
+ }
4562
+ function pasteImage(host, file) {
4563
+ const draw = host.getDraw();
4564
+ const isReadonly = draw.isReadonly();
4565
+ if (isReadonly)
4566
+ return;
4567
+ const rangeManager = draw.getRange();
4568
+ const { startIndex } = rangeManager.getRange();
4569
+ const elementList = draw.getElementList();
4570
+ const fileReader = new FileReader();
4571
+ fileReader.readAsDataURL(file);
4572
+ fileReader.onload = () => {
4573
+ const image = new Image();
4574
+ const value = fileReader.result;
4575
+ image.src = value;
4576
+ image.onload = () => {
4577
+ const imageElement = {
4578
+ value,
4579
+ type: ElementType.IMAGE,
4580
+ width: image.width,
4581
+ height: image.height
4582
+ };
4583
+ if (~startIndex) {
4584
+ formatElementContext(elementList, [imageElement], startIndex);
4585
+ }
4586
+ draw.insertElementList([imageElement]);
4587
+ };
4588
+ };
4589
+ }
4590
+ function pasteByEvent(host, evt) {
4591
+ const draw = host.getDraw();
4592
+ const isReadonly = draw.isReadonly();
4593
+ if (isReadonly)
4594
+ return;
4595
+ const clipboardData = evt.clipboardData;
4596
+ if (!clipboardData)
4597
+ return;
4598
+ const { paste } = draw.getOverride();
4599
+ if (paste) {
4600
+ paste(evt);
4601
+ return;
4602
+ }
4603
+ let isHTML = false;
4604
+ for (let i = 0; i < clipboardData.items.length; i++) {
4605
+ const item = clipboardData.items[i];
4606
+ if (item.type === "text/html") {
4607
+ isHTML = true;
4608
+ break;
4609
+ }
4610
+ }
4611
+ for (let i = 0; i < clipboardData.items.length; i++) {
4612
+ const item = clipboardData.items[i];
4613
+ if (item.kind === "string") {
4614
+ if (item.type === "text/plain" && !isHTML) {
4615
+ item.getAsString((plainText) => {
4616
+ host.input(plainText);
4617
+ });
4618
+ break;
4619
+ }
4620
+ if (item.type === "text/html" && isHTML) {
4621
+ item.getAsString((htmlText) => {
4622
+ pastHTML(host, htmlText);
4623
+ });
4624
+ break;
4625
+ }
4626
+ } else if (item.kind === "file") {
4627
+ if (item.type.includes("image")) {
4628
+ const file = item.getAsFile();
4629
+ if (file) {
4630
+ pasteImage(host, file);
4631
+ }
4632
+ }
4633
+ }
4634
+ }
4635
+ }
4636
+ async function pasteByApi(host, options) {
4637
+ const draw = host.getDraw();
4638
+ const isReadonly = draw.isReadonly();
4639
+ if (isReadonly)
4640
+ return;
4641
+ const { paste } = draw.getOverride();
4642
+ if (paste) {
4643
+ paste();
4644
+ return;
4645
+ }
4646
+ if (options == null ? void 0 : options.isPlainText) {
4647
+ const text = await navigator.clipboard.readText();
4648
+ if (text) {
4649
+ host.input(text);
4650
+ }
4651
+ } else {
4652
+ const clipboardData = await navigator.clipboard.read();
4653
+ let isHTML = false;
4654
+ for (const item of clipboardData) {
4655
+ if (item.types.includes("text/html")) {
4656
+ isHTML = true;
4657
+ break;
4658
+ }
4659
+ }
4660
+ for (const item of clipboardData) {
4661
+ if (item.types.includes("text/plain") && !isHTML) {
4662
+ const textBlob = await item.getType("text/plain");
4663
+ const text = await textBlob.text();
4664
+ if (text) {
4665
+ host.input(text);
4666
+ }
4667
+ } else if (item.types.includes("text/html") && isHTML) {
4668
+ const htmlTextBlob = await item.getType("text/html");
4669
+ const htmlText = await htmlTextBlob.text();
4670
+ if (htmlText) {
4671
+ pastHTML(host, htmlText);
4672
+ }
4673
+ } else if (item.types.some((type) => type.startsWith("image/"))) {
4674
+ const type = item.types.find((type2) => type2.startsWith("image/"));
4675
+ const imageBlob = await item.getType(type);
4676
+ pasteImage(host, imageBlob);
4677
+ }
4678
+ }
4679
+ }
4680
+ }
4519
4681
  class CursorAgent {
4520
4682
  constructor(draw, canvasEvent) {
4521
4683
  __publicField(this, "draw");
@@ -4555,95 +4717,7 @@ class CursorAgent {
4555
4717
  const clipboardData = evt.clipboardData;
4556
4718
  if (!clipboardData)
4557
4719
  return;
4558
- const { paste } = this.draw.getOverride();
4559
- if (paste) {
4560
- paste(evt);
4561
- return;
4562
- }
4563
- const rangeManager = this.draw.getRange();
4564
- const { startIndex } = rangeManager.getRange();
4565
- const elementList = this.draw.getElementList();
4566
- let isHTML = false;
4567
- for (let i = 0; i < clipboardData.items.length; i++) {
4568
- const item = clipboardData.items[i];
4569
- if (item.type === "text/html") {
4570
- isHTML = true;
4571
- break;
4572
- }
4573
- }
4574
- for (let i = 0; i < clipboardData.items.length; i++) {
4575
- const item = clipboardData.items[i];
4576
- if (item.kind === "string") {
4577
- if (item.type === "text/plain" && !isHTML) {
4578
- item.getAsString((plainText) => {
4579
- this.canvasEvent.input(plainText);
4580
- });
4581
- }
4582
- if (item.type === "text/html" && isHTML) {
4583
- item.getAsString((htmlText) => {
4584
- const pasteElementList = getElementListByHTML(htmlText, {
4585
- innerWidth: this.draw.getOriginalInnerWidth()
4586
- });
4587
- if (~startIndex && !rangeManager.getIsSelectAll()) {
4588
- const anchorElement = elementList[startIndex];
4589
- if ((anchorElement == null ? void 0 : anchorElement.titleId) || (anchorElement == null ? void 0 : anchorElement.listId)) {
4590
- let start = 0;
4591
- while (start < pasteElementList.length) {
4592
- const pasteElement = pasteElementList[start];
4593
- if (anchorElement.titleId && /^\n/.test(pasteElement.value)) {
4594
- break;
4595
- }
4596
- if (VIRTUAL_ELEMENT_TYPE.includes(pasteElement.type)) {
4597
- pasteElementList.splice(start, 1);
4598
- if (pasteElement.valueList) {
4599
- for (let v = 0; v < pasteElement.valueList.length; v++) {
4600
- const element = pasteElement.valueList[v];
4601
- if (element.value === ZERO || element.value === "\n") {
4602
- continue;
4603
- }
4604
- pasteElementList.splice(start, 0, element);
4605
- start++;
4606
- }
4607
- }
4608
- start--;
4609
- }
4610
- start++;
4611
- }
4612
- }
4613
- formatElementContext(elementList, pasteElementList, startIndex, {
4614
- isBreakWhenWrap: true
4615
- });
4616
- }
4617
- this.draw.insertElementList(pasteElementList);
4618
- });
4619
- }
4620
- } else if (item.kind === "file") {
4621
- if (item.type.includes("image")) {
4622
- const file = item.getAsFile();
4623
- if (file) {
4624
- const fileReader = new FileReader();
4625
- fileReader.readAsDataURL(file);
4626
- fileReader.onload = () => {
4627
- const image = new Image();
4628
- const value = fileReader.result;
4629
- image.src = value;
4630
- image.onload = () => {
4631
- const imageElement = {
4632
- value,
4633
- type: ElementType.IMAGE,
4634
- width: image.width,
4635
- height: image.height
4636
- };
4637
- if (~startIndex) {
4638
- formatElementContext(elementList, [imageElement], startIndex);
4639
- }
4640
- this.draw.insertElementList([imageElement]);
4641
- };
4642
- };
4643
- }
4644
- }
4645
- }
4646
- }
4720
+ pasteByEvent(this.canvasEvent, evt);
4647
4721
  evt.preventDefault();
4648
4722
  }
4649
4723
  _compositionstart() {
@@ -5330,6 +5404,7 @@ function keydown(evt, host) {
5330
5404
  }
5331
5405
  if (curIndex === null)
5332
5406
  return;
5407
+ draw.getGlobalEvent().setCanvasEventAbility();
5333
5408
  rangeManager.setRange(curIndex, curIndex);
5334
5409
  draw.render({ curIndex });
5335
5410
  } else if (evt.key === KeyMap.Delete) {
@@ -5350,6 +5425,7 @@ function keydown(evt, host) {
5350
5425
  }
5351
5426
  if (curIndex === null)
5352
5427
  return;
5428
+ draw.getGlobalEvent().setCanvasEventAbility();
5353
5429
  rangeManager.setRange(curIndex, curIndex);
5354
5430
  draw.render({ curIndex });
5355
5431
  } else if (evt.key === KeyMap.Enter) {
@@ -7050,6 +7126,8 @@ class RangeManager {
7050
7126
  const elementList = this.draw.getElementList();
7051
7127
  const range = this.getRange();
7052
7128
  const { startIndex, endIndex } = range;
7129
+ if (!~startIndex && !~endIndex)
7130
+ return;
7053
7131
  const startElement = elementList[startIndex];
7054
7132
  const endElement = elementList[endIndex];
7055
7133
  if (startIndex === endIndex) {
@@ -7685,12 +7763,16 @@ class PageNumber {
7685
7763
  class ScrollObserver {
7686
7764
  constructor(draw) {
7687
7765
  __publicField(this, "draw");
7766
+ __publicField(this, "options");
7767
+ __publicField(this, "scrollContainer");
7688
7768
  __publicField(this, "_observer", debounce(() => {
7689
7769
  const { intersectionPageNo, visiblePageNoList } = this.getPageVisibleInfo();
7690
7770
  this.draw.setIntersectionPageNo(intersectionPageNo);
7691
7771
  this.draw.setVisiblePageNoList(visiblePageNoList);
7692
7772
  }, 150));
7693
7773
  this.draw = draw;
7774
+ this.options = draw.getOptions();
7775
+ this.scrollContainer = this.getScrollContainer();
7694
7776
  setTimeout(() => {
7695
7777
  if (!window.scrollY) {
7696
7778
  this._observer();
@@ -7698,15 +7780,18 @@ class ScrollObserver {
7698
7780
  });
7699
7781
  this._addEvent();
7700
7782
  }
7783
+ getScrollContainer() {
7784
+ return this.options.scrollContainerSelector ? document.querySelector(this.options.scrollContainerSelector) || document : document;
7785
+ }
7701
7786
  _addEvent() {
7702
- document.addEventListener("scroll", this._observer);
7787
+ this.scrollContainer.addEventListener("scroll", this._observer);
7703
7788
  }
7704
7789
  removeEvent() {
7705
- document.removeEventListener("scroll", this._observer);
7790
+ this.scrollContainer.removeEventListener("scroll", this._observer);
7706
7791
  }
7707
7792
  getElementVisibleInfo(element) {
7708
7793
  const rect = element.getBoundingClientRect();
7709
- const viewHeight = Math.max(document.documentElement.clientHeight, window.innerHeight);
7794
+ const viewHeight = this.scrollContainer === document ? Math.max(document.documentElement.clientHeight, window.innerHeight) : this.scrollContainer.clientHeight;
7710
7795
  const visibleHeight = Math.min(rect.bottom, viewHeight) - Math.max(rect.top, 0);
7711
7796
  return {
7712
7797
  intersectionHeight: visibleHeight > 0 ? visibleHeight : 0
@@ -11860,6 +11945,9 @@ class Draw {
11860
11945
  getCanvasEvent() {
11861
11946
  return this.canvasEvent;
11862
11947
  }
11948
+ getGlobalEvent() {
11949
+ return this.globalEvent;
11950
+ }
11863
11951
  getListener() {
11864
11952
  return this.listener;
11865
11953
  }
@@ -12016,6 +12104,9 @@ class Draw {
12016
12104
  if (this.listener.pageScaleChange) {
12017
12105
  this.listener.pageScaleChange(payload);
12018
12106
  }
12107
+ if (this.eventBus.isSubscribe("pageScaleChange")) {
12108
+ this.eventBus.emit("pageScaleChange", payload);
12109
+ }
12019
12110
  }
12020
12111
  getPagePixelRatio() {
12021
12112
  return this.pagePixelRatio || window.devicePixelRatio;
@@ -13179,14 +13270,11 @@ class CommandAdapt {
13179
13270
  copy() {
13180
13271
  this.canvasEvent.copy();
13181
13272
  }
13182
- async paste() {
13273
+ paste(payload) {
13183
13274
  const isReadonly = this.draw.isReadonly();
13184
13275
  if (isReadonly)
13185
13276
  return;
13186
- const text = await navigator.clipboard.readText();
13187
- if (text) {
13188
- this.canvasEvent.input(text);
13189
- }
13277
+ pasteByApi(this.canvasEvent, payload);
13190
13278
  }
13191
13279
  selectAll() {
13192
13280
  this.canvasEvent.selectAll();
@@ -13905,45 +13993,52 @@ class CommandAdapt {
13905
13993
  const positionContext = this.position.getPositionContext();
13906
13994
  if (!positionContext.isTable)
13907
13995
  return;
13908
- const { index: index2, trIndex } = positionContext;
13996
+ const { index: index2, trIndex, tdIndex } = positionContext;
13909
13997
  const originalElementList = this.draw.getOriginalElementList();
13910
13998
  const element = originalElementList[index2];
13911
- const curTrList = element.trList;
13912
- const curTr = curTrList[trIndex];
13913
- if (curTrList.length <= 1) {
13999
+ const trList = element.trList;
14000
+ const curTr = trList[trIndex];
14001
+ const curTdRowIndex = curTr.tdList[tdIndex].rowIndex;
14002
+ if (trList.length <= 1) {
13914
14003
  this.deleteTable();
13915
14004
  return;
13916
14005
  }
14006
+ for (let r = 0; r < curTdRowIndex; r++) {
14007
+ const tr = trList[r];
14008
+ const tdList = tr.tdList;
14009
+ for (let d = 0; d < tdList.length; d++) {
14010
+ const td = tdList[d];
14011
+ if (td.rowIndex + td.rowspan > curTdRowIndex) {
14012
+ td.rowspan--;
14013
+ }
14014
+ }
14015
+ }
13917
14016
  for (let d = 0; d < curTr.tdList.length; d++) {
13918
14017
  const td = curTr.tdList[d];
13919
14018
  if (td.rowspan > 1) {
13920
- let start = trIndex + 1;
13921
- while (start < trIndex + td.rowspan) {
13922
- const tdId = getUUID();
13923
- const tr = curTrList[start];
13924
- tr.tdList.splice(d, 0, {
13925
- id: tdId,
13926
- rowspan: 1,
13927
- colspan: 1,
13928
- value: [
13929
- {
13930
- value: ZERO,
13931
- size: 16,
13932
- tableId: element.id,
13933
- trId: tr.id,
13934
- tdId
13935
- }
13936
- ]
13937
- });
13938
- start += 1;
13939
- }
14019
+ const tdId = getUUID();
14020
+ const nextTr = trList[trIndex + 1];
14021
+ nextTr.tdList.splice(d, 0, {
14022
+ id: tdId,
14023
+ rowspan: td.rowspan - 1,
14024
+ colspan: td.colspan,
14025
+ value: [
14026
+ {
14027
+ value: ZERO,
14028
+ size: 16,
14029
+ tableId: element.id,
14030
+ trId: nextTr.id,
14031
+ tdId
14032
+ }
14033
+ ]
14034
+ });
13940
14035
  }
13941
14036
  }
13942
- curTrList.splice(trIndex, 1);
14037
+ trList.splice(trIndex, 1);
13943
14038
  this.position.setPositionContext({
13944
14039
  isTable: false
13945
14040
  });
13946
- this.range.setRange(0, 0);
14041
+ this.range.clearRange();
13947
14042
  this.draw.render({
13948
14043
  curIndex: positionContext.index
13949
14044
  });
@@ -14754,10 +14849,10 @@ class CommandAdapt {
14754
14849
  const startPageNo = positionList[startIndex].pageNo;
14755
14850
  const endPageNo = positionList[endIndex].pageNo;
14756
14851
  const rangeRects = [];
14852
+ const height = this.draw.getOriginalHeight();
14853
+ const pageGap = this.draw.getOriginalPageGap();
14757
14854
  const selectionPositionList = this.position.getSelectionPositionList();
14758
14855
  if (selectionPositionList) {
14759
- const height = this.draw.getOriginalHeight();
14760
- const pageGap = this.draw.getOriginalPageGap();
14761
14856
  let currentRowNo = null;
14762
14857
  let currentX = 0;
14763
14858
  let rangeRect = null;
@@ -14782,6 +14877,16 @@ class CommandAdapt {
14782
14877
  rangeRects.push(rangeRect);
14783
14878
  }
14784
14879
  }
14880
+ } else {
14881
+ const positionList2 = this.position.getPositionList();
14882
+ const position = positionList2[endIndex];
14883
+ const { coordinate: { rightTop }, pageNo, lineHeight } = position;
14884
+ rangeRects.push({
14885
+ x: rightTop[0],
14886
+ y: rightTop[1] + pageNo * (height + pageGap),
14887
+ width: 0,
14888
+ height: lineHeight
14889
+ });
14785
14890
  }
14786
14891
  return deepClone({
14787
14892
  isCollapsed,
@@ -16108,7 +16213,8 @@ class Editor {
16108
16213
  printPixelRatio: 3,
16109
16214
  maskMargin: [0, 0, 0, 0],
16110
16215
  letterClass: [LETTER_CLASS.ENGLISH],
16111
- contextMenuDisableKeys: []
16216
+ contextMenuDisableKeys: [],
16217
+ scrollContainerSelector: ""
16112
16218
  }, options), {
16113
16219
  header: headerOptions,
16114
16220
  footer: footerOptions,