@hailin-zheng/editor-core 1.0.10 → 1.0.14

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.
Files changed (300) hide show
  1. package/lib/doc-ruler.d.ts +51 -0
  2. package/lib/doc-ruler.js +313 -0
  3. package/lib/doc-ruler.js.map +1 -0
  4. package/lib/framework/common-util.d.ts +63 -0
  5. package/lib/framework/common-util.js +178 -0
  6. package/lib/framework/common-util.js.map +1 -0
  7. package/lib/framework/document-change.d.ts +265 -0
  8. package/lib/framework/document-change.js +1342 -0
  9. package/lib/framework/document-change.js.map +1 -0
  10. package/lib/framework/document-combine.d.ts +24 -0
  11. package/lib/framework/document-combine.js +40 -0
  12. package/lib/framework/document-combine.js.map +1 -0
  13. package/lib/framework/document-comment.d.ts +46 -0
  14. package/lib/framework/document-comment.js +148 -0
  15. package/lib/framework/document-comment.js.map +1 -0
  16. package/lib/framework/document-context.d.ts +149 -0
  17. package/lib/framework/document-context.js +330 -0
  18. package/lib/framework/document-context.js.map +1 -0
  19. package/lib/framework/document-eval-func.d.ts +18 -0
  20. package/lib/framework/document-eval-func.js +48 -0
  21. package/lib/framework/document-eval-func.js.map +1 -0
  22. package/lib/framework/document-event.d.ts +213 -0
  23. package/lib/framework/document-event.js +1054 -0
  24. package/lib/framework/document-event.js.map +1 -0
  25. package/lib/framework/document-history.d.ts +26 -0
  26. package/lib/framework/document-history.js +65 -0
  27. package/lib/framework/document-history.js.map +1 -0
  28. package/lib/framework/document-images-loader.d.ts +16 -0
  29. package/lib/framework/document-images-loader.js +66 -0
  30. package/lib/framework/document-images-loader.js.map +1 -0
  31. package/lib/framework/document-input-cursor.d.ts +78 -0
  32. package/lib/framework/document-input-cursor.js +239 -0
  33. package/lib/framework/document-input-cursor.js.map +1 -0
  34. package/lib/framework/document-paint.d.ts +34 -0
  35. package/lib/framework/document-paint.js +103 -0
  36. package/lib/framework/document-paint.js.map +1 -0
  37. package/lib/framework/document-print-offscreen.d.ts +38 -0
  38. package/lib/framework/document-print-offscreen.js +128 -0
  39. package/lib/framework/document-print-offscreen.js.map +1 -0
  40. package/lib/framework/document-print.d.ts +60 -0
  41. package/lib/framework/document-print.js +203 -0
  42. package/lib/framework/document-print.js.map +1 -0
  43. package/lib/framework/document-segmenter.d.ts +2 -0
  44. package/lib/framework/document-segmenter.js +106 -0
  45. package/lib/framework/document-segmenter.js.map +1 -0
  46. package/lib/framework/document-selection.d.ts +89 -0
  47. package/lib/framework/document-selection.js +358 -0
  48. package/lib/framework/document-selection.js.map +1 -0
  49. package/lib/framework/document-template.d.ts +4 -0
  50. package/lib/framework/document-template.js +20 -0
  51. package/lib/framework/document-template.js.map +1 -0
  52. package/lib/framework/document-textline-mode.d.ts +7 -0
  53. package/lib/framework/document-textline-mode.js +30 -0
  54. package/lib/framework/document-textline-mode.js.map +1 -0
  55. package/lib/framework/element-define.d.ts +319 -0
  56. package/lib/framework/element-define.js +579 -0
  57. package/lib/framework/element-define.js.map +1 -0
  58. package/lib/framework/element-event-define.d.ts +98 -0
  59. package/lib/framework/element-event-define.js +108 -0
  60. package/lib/framework/element-event-define.js.map +1 -0
  61. package/lib/framework/element-measure.d.ts +97 -0
  62. package/lib/framework/element-measure.js +551 -0
  63. package/lib/framework/element-measure.js.map +1 -0
  64. package/lib/framework/element-paint.d.ts +42 -0
  65. package/lib/framework/element-paint.js +170 -0
  66. package/lib/framework/element-paint.js.map +1 -0
  67. package/lib/framework/element-props.d.ts +301 -0
  68. package/lib/framework/element-props.js +809 -0
  69. package/lib/framework/element-props.js.map +1 -0
  70. package/lib/framework/element-reader.d.ts +19 -0
  71. package/lib/framework/element-reader.js +151 -0
  72. package/lib/framework/element-reader.js.map +1 -0
  73. package/lib/framework/element-render-cut.d.ts +55 -0
  74. package/lib/framework/element-render-cut.js +449 -0
  75. package/lib/framework/element-render-cut.js.map +1 -0
  76. package/lib/framework/element-serialize.d.ts +30 -0
  77. package/lib/framework/element-serialize.js +113 -0
  78. package/lib/framework/element-serialize.js.map +1 -0
  79. package/lib/framework/element-util.d.ts +369 -0
  80. package/lib/framework/element-util.js +1463 -0
  81. package/lib/framework/element-util.js.map +1 -0
  82. package/lib/framework/impl/checkbox/checkbox-impl.d.ts +24 -0
  83. package/lib/framework/impl/checkbox/checkbox-impl.js +64 -0
  84. package/lib/framework/impl/checkbox/checkbox-impl.js.map +1 -0
  85. package/lib/framework/impl/comments/comment-content-impl.d.ts +40 -0
  86. package/lib/framework/impl/comments/comment-content-impl.js +105 -0
  87. package/lib/framework/impl/comments/comment-content-impl.js.map +1 -0
  88. package/lib/framework/impl/comments/comment-element-impl.d.ts +21 -0
  89. package/lib/framework/impl/comments/comment-element-impl.js +62 -0
  90. package/lib/framework/impl/comments/comment-element-impl.js.map +1 -0
  91. package/lib/framework/impl/comments/comments-container-impl.d.ts +22 -0
  92. package/lib/framework/impl/comments/comments-container-impl.js +62 -0
  93. package/lib/framework/impl/comments/comments-container-impl.js.map +1 -0
  94. package/lib/framework/impl/comments/comments-util.d.ts +12 -0
  95. package/lib/framework/impl/comments/comments-util.js +67 -0
  96. package/lib/framework/impl/comments/comments-util.js.map +1 -0
  97. package/lib/framework/impl/comments/validate-msg-impl.d.ts +21 -0
  98. package/lib/framework/impl/comments/validate-msg-impl.js +83 -0
  99. package/lib/framework/impl/comments/validate-msg-impl.js.map +1 -0
  100. package/lib/framework/impl/data-element/data-decorate-impl.d.ts +30 -0
  101. package/lib/framework/impl/data-element/data-decorate-impl.js +91 -0
  102. package/lib/framework/impl/data-element/data-decorate-impl.js.map +1 -0
  103. package/lib/framework/impl/data-element/data-element-barcode.d.ts +31 -0
  104. package/lib/framework/impl/data-element/data-element-barcode.js +115 -0
  105. package/lib/framework/impl/data-element/data-element-barcode.js.map +1 -0
  106. package/lib/framework/impl/data-element/data-element-base-impl.d.ts +68 -0
  107. package/lib/framework/impl/data-element/data-element-base-impl.js +205 -0
  108. package/lib/framework/impl/data-element/data-element-base-impl.js.map +1 -0
  109. package/lib/framework/impl/data-element/data-element-check-impl.d.ts +35 -0
  110. package/lib/framework/impl/data-element/data-element-check-impl.js +133 -0
  111. package/lib/framework/impl/data-element/data-element-check-impl.js.map +1 -0
  112. package/lib/framework/impl/data-element/data-element-date-impl.d.ts +23 -0
  113. package/lib/framework/impl/data-element/data-element-date-impl.js +111 -0
  114. package/lib/framework/impl/data-element/data-element-date-impl.js.map +1 -0
  115. package/lib/framework/impl/data-element/data-element-group-impl.d.ts +23 -0
  116. package/lib/framework/impl/data-element/data-element-group-impl.js +130 -0
  117. package/lib/framework/impl/data-element/data-element-group-impl.js.map +1 -0
  118. package/lib/framework/impl/data-element/data-element-image-impl.d.ts +30 -0
  119. package/lib/framework/impl/data-element/data-element-image-impl.js +137 -0
  120. package/lib/framework/impl/data-element/data-element-image-impl.js.map +1 -0
  121. package/lib/framework/impl/data-element/data-element-list-impl.d.ts +22 -0
  122. package/lib/framework/impl/data-element/data-element-list-impl.js +131 -0
  123. package/lib/framework/impl/data-element/data-element-list-impl.js.map +1 -0
  124. package/lib/framework/impl/data-element/data-element-text-impl.d.ts +23 -0
  125. package/lib/framework/impl/data-element/data-element-text-impl.js +103 -0
  126. package/lib/framework/impl/data-element/data-element-text-impl.js.map +1 -0
  127. package/lib/framework/impl/decorate/fill-null-space-imple.d.ts +21 -0
  128. package/lib/framework/impl/decorate/fill-null-space-imple.js +43 -0
  129. package/lib/framework/impl/decorate/fill-null-space-imple.js.map +1 -0
  130. package/lib/framework/impl/document/doc-body-impl.d.ts +27 -0
  131. package/lib/framework/impl/document/doc-body-impl.js +79 -0
  132. package/lib/framework/impl/document/doc-body-impl.js.map +1 -0
  133. package/lib/framework/impl/document/doc-body-part-impl.d.ts +30 -0
  134. package/lib/framework/impl/document/doc-body-part-impl.js +94 -0
  135. package/lib/framework/impl/document/doc-body-part-impl.js.map +1 -0
  136. package/lib/framework/impl/document/doc-container-impl.d.ts +16 -0
  137. package/lib/framework/impl/document/doc-container-impl.js +21 -0
  138. package/lib/framework/impl/document/doc-container-impl.js.map +1 -0
  139. package/lib/framework/impl/document/doc-footer-impl.d.ts +26 -0
  140. package/lib/framework/impl/document/doc-footer-impl.js +77 -0
  141. package/lib/framework/impl/document/doc-footer-impl.js.map +1 -0
  142. package/lib/framework/impl/document/doc-header-impl.d.ts +26 -0
  143. package/lib/framework/impl/document/doc-header-impl.js +83 -0
  144. package/lib/framework/impl/document/doc-header-impl.js.map +1 -0
  145. package/lib/framework/impl/document/doc-impl.d.ts +61 -0
  146. package/lib/framework/impl/document/doc-impl.js +209 -0
  147. package/lib/framework/impl/document/doc-impl.js.map +1 -0
  148. package/lib/framework/impl/media-formula/menstrual-history.d.ts +35 -0
  149. package/lib/framework/impl/media-formula/menstrual-history.js +153 -0
  150. package/lib/framework/impl/media-formula/menstrual-history.js.map +1 -0
  151. package/lib/framework/impl/paragraph/p-impl.d.ts +45 -0
  152. package/lib/framework/impl/paragraph/p-impl.js +156 -0
  153. package/lib/framework/impl/paragraph/p-impl.js.map +1 -0
  154. package/lib/framework/impl/picture/image-impl.d.ts +31 -0
  155. package/lib/framework/impl/picture/image-impl.js +124 -0
  156. package/lib/framework/impl/picture/image-impl.js.map +1 -0
  157. package/lib/framework/impl/radio/radio-impl.d.ts +22 -0
  158. package/lib/framework/impl/radio/radio-impl.js +72 -0
  159. package/lib/framework/impl/radio/radio-impl.js.map +1 -0
  160. package/lib/framework/impl/symbol/br-symbol-impl.d.ts +22 -0
  161. package/lib/framework/impl/symbol/br-symbol-impl.js +54 -0
  162. package/lib/framework/impl/symbol/br-symbol-impl.js.map +1 -0
  163. package/lib/framework/impl/symbol/p-symbol-impl.d.ts +19 -0
  164. package/lib/framework/impl/symbol/p-symbol-impl.js +54 -0
  165. package/lib/framework/impl/symbol/p-symbol-impl.js.map +1 -0
  166. package/lib/framework/impl/table/table-cell-impl.d.ts +37 -0
  167. package/lib/framework/impl/table/table-cell-impl.js +145 -0
  168. package/lib/framework/impl/table/table-cell-impl.js.map +1 -0
  169. package/lib/framework/impl/table/table-impl.d.ts +55 -0
  170. package/lib/framework/impl/table/table-impl.js +363 -0
  171. package/lib/framework/impl/table/table-impl.js.map +1 -0
  172. package/lib/framework/impl/table/table-row-impl.d.ts +26 -0
  173. package/lib/framework/impl/table/table-row-impl.js +75 -0
  174. package/lib/framework/impl/table/table-row-impl.js.map +1 -0
  175. package/lib/framework/impl/table/table-split-cell-patch.d.ts +20 -0
  176. package/lib/framework/impl/table/table-split-cell-patch.js +89 -0
  177. package/lib/framework/impl/table/table-split-cell-patch.js.map +1 -0
  178. package/lib/framework/impl/table/table-split-cell.d.ts +90 -0
  179. package/lib/framework/impl/table/table-split-cell.js +464 -0
  180. package/lib/framework/impl/table/table-split-cell.js.map +1 -0
  181. package/lib/framework/impl/table/table-util.d.ts +150 -0
  182. package/lib/framework/impl/table/table-util.js +678 -0
  183. package/lib/framework/impl/table/table-util.js.map +1 -0
  184. package/lib/framework/impl/text/text-impl.d.ts +32 -0
  185. package/lib/framework/impl/text/text-impl.js +149 -0
  186. package/lib/framework/impl/text/text-impl.js.map +1 -0
  187. package/lib/framework/impl/text/track-run-impl.d.ts +27 -0
  188. package/lib/framework/impl/text/track-run-impl.js +112 -0
  189. package/lib/framework/impl/text/track-run-impl.js.map +1 -0
  190. package/lib/framework/notify.d.ts +13 -0
  191. package/lib/framework/notify.js +116 -0
  192. package/lib/framework/notify.js.map +1 -0
  193. package/lib/framework/range-util.d.ts +40 -0
  194. package/lib/framework/range-util.js +312 -0
  195. package/lib/framework/range-util.js.map +1 -0
  196. package/lib/framework/render-context.d.ts +91 -0
  197. package/lib/framework/render-context.js +384 -0
  198. package/lib/framework/render-context.js.map +1 -0
  199. package/lib/framework/render-define.d.ts +109 -0
  200. package/lib/framework/render-define.js +195 -0
  201. package/lib/framework/render-define.js.map +1 -0
  202. package/lib/framework/selection-overlays.d.ts +30 -0
  203. package/lib/framework/selection-overlays.js +124 -0
  204. package/lib/framework/selection-overlays.js.map +1 -0
  205. package/lib/texteditor.d.ts +318 -0
  206. package/lib/texteditor.js +913 -0
  207. package/lib/texteditor.js.map +1 -0
  208. package/lib/util/subject.d.ts +34 -0
  209. package/lib/util/subject.js +88 -0
  210. package/lib/util/subject.js.map +1 -0
  211. package/{src/med_editor/util/table-bind.ts → lib/util/table-bind.d.ts} +2 -3
  212. package/lib/util/table-bind.js +6 -0
  213. package/lib/util/table-bind.js.map +1 -0
  214. package/package.json +2 -2
  215. package/src/med_editor/doc-ruler.ts +0 -340
  216. package/src/med_editor/framework/common-util.ts +0 -200
  217. package/src/med_editor/framework/document-change.ts +0 -1391
  218. package/src/med_editor/framework/document-combine.ts +0 -44
  219. package/src/med_editor/framework/document-comment.ts +0 -163
  220. package/src/med_editor/framework/document-context.ts +0 -410
  221. package/src/med_editor/framework/document-eval-func.ts +0 -53
  222. package/src/med_editor/framework/document-event.ts +0 -1082
  223. package/src/med_editor/framework/document-history.ts +0 -76
  224. package/src/med_editor/framework/document-images-loader.ts +0 -74
  225. package/src/med_editor/framework/document-input-cursor.ts +0 -244
  226. package/src/med_editor/framework/document-paint.ts +0 -110
  227. package/src/med_editor/framework/document-print-offscreen.ts +0 -134
  228. package/src/med_editor/framework/document-print.ts +0 -219
  229. package/src/med_editor/framework/document-segmenter.ts +0 -211
  230. package/src/med_editor/framework/document-selection.ts +0 -389
  231. package/src/med_editor/framework/document-template.ts +0 -20
  232. package/src/med_editor/framework/document-textline-mode.ts +0 -34
  233. package/src/med_editor/framework/element-define.ts +0 -674
  234. package/src/med_editor/framework/element-event-define.ts +0 -141
  235. package/src/med_editor/framework/element-measure.ts +0 -573
  236. package/src/med_editor/framework/element-paint.ts +0 -176
  237. package/src/med_editor/framework/element-props.ts +0 -938
  238. package/src/med_editor/framework/element-reader.ts +0 -159
  239. package/src/med_editor/framework/element-render-cut.ts +0 -456
  240. package/src/med_editor/framework/element-serialize.ts +0 -126
  241. package/src/med_editor/framework/element-util.ts +0 -1564
  242. package/src/med_editor/framework/impl/checkbox/checkbox-impl.ts +0 -71
  243. package/src/med_editor/framework/impl/comments/comment-content-impl.ts +0 -119
  244. package/src/med_editor/framework/impl/comments/comment-element-impl.ts +0 -65
  245. package/src/med_editor/framework/impl/comments/comments-container-impl.ts +0 -68
  246. package/src/med_editor/framework/impl/comments/comments-util.ts +0 -84
  247. package/src/med_editor/framework/impl/comments/validate-msg-impl.ts +0 -94
  248. package/src/med_editor/framework/impl/data-element/data-decorate-impl.ts +0 -95
  249. package/src/med_editor/framework/impl/data-element/data-element-barcode.ts +0 -127
  250. package/src/med_editor/framework/impl/data-element/data-element-base-impl.ts +0 -234
  251. package/src/med_editor/framework/impl/data-element/data-element-check-impl.ts +0 -146
  252. package/src/med_editor/framework/impl/data-element/data-element-date-impl.ts +0 -128
  253. package/src/med_editor/framework/impl/data-element/data-element-group-impl.ts +0 -150
  254. package/src/med_editor/framework/impl/data-element/data-element-image-impl.ts +0 -147
  255. package/src/med_editor/framework/impl/data-element/data-element-list-impl.ts +0 -142
  256. package/src/med_editor/framework/impl/data-element/data-element-text-impl.ts +0 -117
  257. package/src/med_editor/framework/impl/decorate/fill-null-space-imple.ts +0 -48
  258. package/src/med_editor/framework/impl/document/doc-body-impl.ts +0 -95
  259. package/src/med_editor/framework/impl/document/doc-body-part-impl.ts +0 -104
  260. package/src/med_editor/framework/impl/document/doc-container-impl.ts +0 -24
  261. package/src/med_editor/framework/impl/document/doc-footer-impl.ts +0 -88
  262. package/src/med_editor/framework/impl/document/doc-header-impl.ts +0 -100
  263. package/src/med_editor/framework/impl/document/doc-impl.ts +0 -226
  264. package/src/med_editor/framework/impl/media-formula/menstrual-history.ts +0 -175
  265. package/src/med_editor/framework/impl/paragraph/p-impl.ts +0 -190
  266. package/src/med_editor/framework/impl/picture/image-impl.ts +0 -136
  267. package/src/med_editor/framework/impl/radio/radio-impl.ts +0 -79
  268. package/src/med_editor/framework/impl/symbol/br-symbol-impl.ts +0 -60
  269. package/src/med_editor/framework/impl/symbol/p-symbol-impl.ts +0 -57
  270. package/src/med_editor/framework/impl/table/table-cell-impl.ts +0 -156
  271. package/src/med_editor/framework/impl/table/table-impl.ts +0 -401
  272. package/src/med_editor/framework/impl/table/table-row-impl.ts +0 -83
  273. package/src/med_editor/framework/impl/table/table-split-cell-patch.ts +0 -98
  274. package/src/med_editor/framework/impl/table/table-split-cell.ts +0 -475
  275. package/src/med_editor/framework/impl/table/table-util.ts +0 -716
  276. package/src/med_editor/framework/impl/text/text-impl.ts +0 -163
  277. package/src/med_editor/framework/impl/text/track-run-impl.ts +0 -135
  278. package/src/med_editor/framework/notify.ts +0 -130
  279. package/src/med_editor/framework/range-util.ts +0 -321
  280. package/src/med_editor/framework/render-context.ts +0 -431
  281. package/src/med_editor/framework/render-define.ts +0 -224
  282. package/src/med_editor/framework/selection-overlays.ts +0 -133
  283. package/src/med_editor/texteditor.ts +0 -1010
  284. package/src/med_editor/util/subject.ts +0 -118
  285. package/src/med_editor//345/205/245/351/231/242/350/256/260/345/275/225.json +0 -3573
  286. package/src/med_editor//345/205/245/351/231/242/350/256/260/345/275/225/346/265/213/350/257/225.json +0 -3573
  287. package/src/med_editor//345/205/245/351/231/242/350/256/260/345/275/225/346/265/213/350/257/225bug.json +0 -315
  288. package/src/med_editor//345/205/245/351/231/242/350/256/260/345/275/225/346/265/213/350/257/225/346/211/271/346/263/250.json +0 -122
  289. package/src/med_editor//345/205/245/351/231/242/350/256/260/345/275/225/346/265/213/350/257/225/346/226/207/346/241/243/351/252/214/350/257/201.json +0 -3599
  290. package/src/med_editor//345/205/245/351/231/242/350/256/260/345/275/225/346/265/213/350/257/225/351/225/277/346/226/207/346/234/254.json +0 -24586
  291. package/src/med_editor//345/220/210/345/271/266/347/227/205/347/250/213/345/275/225.json +0 -2874
  292. package/src/med_editor//346/211/213/346/234/257/350/256/260/345/275/225.json +0 -341
  293. package/src/med_editor//346/231/256/351/200/232doc/347/261/273/346/226/207/346/241/243.json +0 -2201
  294. package/src/med_editor//346/243/200/351/252/214/347/224/263/350/257/267/345/215/225.json +0 -1069
  295. package/src/med_editor//347/227/205/347/250/213/345/275/225//345/206/205/351/225/234/344/270/213/346/262/273/347/226/227/350/256/260/345/275/225.json +0 -125
  296. package/src/med_editor//347/227/205/347/250/213/345/275/225//345/220/210/345/271/266/347/227/205/347/250/213/345/275/225/346/250/241/346/235/277.json +0 -86
  297. package/src/med_editor//347/227/205/347/250/213/345/275/225//346/227/245/345/270/270/347/227/205/347/250/213/350/256/260/345/275/225.json +0 -115
  298. package/src/med_editor//347/227/205/347/250/213/345/275/225//346/237/245/346/210/277/350/256/260/345/275/2251.json +0 -108
  299. package/src/med_editor//347/227/205/347/250/213/345/275/225//351/246/226/346/254/241/344/270/212/347/272/247/345/214/273/345/270/210/346/237/245/346/210/277/350/256/260/345/275/225.json +0 -272
  300. package/src/med_editor//351/225/277/346/234/237/345/214/273/345/230/261/345/215/225.json +0 -1070
@@ -1,1391 +0,0 @@
1
- import { ICompositionStartInfo, InputData } from "./document-input-cursor";
2
- import { SelectionRange, SelectionState } from "./document-selection";
3
- import { ElementUtil } from "./element-util";
4
- import {
5
- BlockContainerElement,
6
- BlockContentElement,
7
- BranchElement,
8
- DocMode,
9
- Element,
10
- InlineGroupElement,
11
- LeafElement,
12
- SelectionContentRange,
13
- ViewOptions
14
- } from "./element-define";
15
- import { TextGroupElement } from "./impl/text/text-impl";
16
- import { PSymbolElement } from "./impl/symbol/p-symbol-impl";
17
- import { ParagraphElement } from "./impl/paragraph/p-impl";
18
- import { RangeUtil } from "./range-util";
19
- import { TableElement } from "./impl/table/table-impl";
20
- import { DocumentEvent } from "./document-event";
21
- import { KeyboradElementEvent } from "./element-event-define";
22
- import { DataEleBaseProps, ParagraphProps, TextProps } from "./element-props";
23
- import { ElementSerialize } from "./element-serialize";
24
- import { ElementReader } from "./element-reader";
25
- import { BreakElement } from "./impl/symbol/br-symbol-impl";
26
- import { DataDecorateElement } from "./impl/data-element/data-decorate-impl";
27
- import { EditorContext } from "./document-context";
28
- import {
29
- DataElementInlineGroup,
30
- InlineGroupInputElement,
31
- IsInSideDataElement,
32
- IsInSideInlineGroupInputElement
33
- } from "./impl/data-element/data-element-base-impl";
34
- import { DocumentComment } from "./document-comment";
35
- import { CommentElement } from "./impl/comments/comment-element-impl";
36
- import { nanoid } from "nanoid";
37
- import { CommContentElement } from "./impl/comments/comment-content-impl";
38
- import { ValidateElement } from "./impl/comments/validate-msg-impl";
39
- import { CommonUtil } from "./common-util";
40
- import { TrackRunElement, TrackRunTypeEnum } from "./impl/text/track-run-impl";
41
- import { DocumentBodyElement } from "./impl/document/doc-body-impl";
42
-
43
- /**
44
- * 文档内容改变
45
- */
46
- export class DocumentChange {
47
- constructor(private selectionState: SelectionState, private viewOptions: ViewOptions, private eleReader: ElementReader, private docCtx: EditorContext, private docComment: DocumentComment) {
48
- }
49
-
50
- newInput(data: InputData): void {
51
- const { startControl, startOffset, collapsed, enableTrackChanges } = this.selectionState;
52
- if (!collapsed) {
53
- this.onInputBySelection(data);
54
- return;
55
- }
56
- //判断是否需要创建新的留痕区域
57
- if (enableTrackChanges && !this.isInCorrectTrackRegion(startControl as Element, TrackRunTypeEnum.Inserted)) {
58
- this.newInputTrackChanges(data, startControl as LeafElement, startOffset);
59
- return;
60
- }
61
- //当前输入节点是在留痕区域中,但是当前关闭了审阅模式,需要拆分留痕区域,创建新输入节点
62
- if (!enableTrackChanges && this.isInTrackBlock(startControl)) {
63
- const newInput = this.splitTrackElement(startControl, startOffset);
64
- const comp = data.compositionStartInfo as ICompositionStartInfo;
65
- comp.element = newInput;
66
- comp.offset = 0;
67
- this.inputTextGroup(newInput, data);
68
- return;
69
- }
70
- if (!(startControl instanceof TextGroupElement)) {
71
- if (!data.compositionStartInfo) {
72
- throw new Error('compositionStartInfo is null');
73
- }
74
- const siblingTextEle = startOffset === 1 ? ElementUtil.getNextSiblingElement(startControl) : ElementUtil.getPrevSiblingElement(startControl);
75
- if (siblingTextEle instanceof TextGroupElement) {
76
- data.compositionStartInfo.offset = startOffset === 0 ? siblingTextEle.text.length : 0;
77
- this.inputTextGroup(siblingTextEle, data);
78
- } else {
79
- const inputTextProps = this.getDefaultTextProps(startControl, startOffset);
80
- const newTextGroup = ElementUtil.getNewTextGroup(inputTextProps);
81
- startControl.parent.addChild(newTextGroup, startControl.getIndex() + startOffset);
82
- this.inputTextGroup(newTextGroup, data);
83
- }
84
- return;
85
- }
86
- this.inputTextGroup(startControl, data);
87
- }
88
-
89
-
90
- /**
91
- * 选中区域后进行输入
92
- * 需要处理将选中的区域删除后,进行输入的情况
93
- */
94
- onInputBySelection(data: InputData): void {
95
- this.onRangeDelete();
96
- this.selectionState.afterSelectionChanged = (newVal) => {
97
- const { startControl, startOffset, editable } = newVal;
98
- if (!editable) {
99
- return false;
100
- }
101
- const comp = data.compositionStartInfo as ICompositionStartInfo;
102
- comp.element = startControl;
103
- comp.offset = startOffset;
104
- this.newInput(data);
105
- return true;
106
- };
107
-
108
- }
109
-
110
- /**
111
- * 当前元素是否在正确的留痕区域(ins-run、del-run),情况分为以下情况
112
- * 1.留痕块类型为新增,但是留痕块的创建者为其他用户,此时需要拆分留痕区域
113
- * 2.留痕块为当前用户创建,但是创建时间大于有效的时间,此时需要拆分留痕区域
114
- * @param startControl
115
- * @param trackType
116
- * @returns
117
- */
118
- isInCorrectTrackRegion(startControl: Element, trackType: TrackRunTypeEnum): boolean {
119
- const parent = startControl.parent;
120
- return parent instanceof TrackRunElement
121
- && parent.props.userId === this.viewOptions.editUser.id
122
- && parent.type === trackType
123
- && CommonUtil.getNowDiffSeconds(parent.props.date) <= this.viewOptions.trackChangePeriod;
124
- }
125
-
126
- /**
127
- * 当前元素是否在留痕区域(ins-run、del-run)中
128
- * @param target
129
- * @param trackType
130
- * @returns
131
- */
132
- isInTrackBlock(target: Element, trackType: TrackRunTypeEnum | null = null): boolean {
133
- return target.parent instanceof TrackRunElement && (trackType === null || target.parent.type === trackType);
134
- }
135
-
136
- /**
137
- * 留痕输入
138
- * @param data
139
- * @param startControl
140
- * @param startOffset
141
- * @returns
142
- */
143
- newInputTrackChanges(data: InputData, startControl: LeafElement, startOffset: number): void {
144
- const userId = this.viewOptions.editUser.id;
145
- const compInfo = data.compositionStartInfo as ICompositionStartInfo;
146
- if (this.isInCorrectTrackRegion(startControl, TrackRunTypeEnum.Inserted)) {
147
- return;
148
- }
149
- if (this.isInTrackBlock(startControl)) {
150
- const newInput = this.createNewTrackInput(startControl, startOffset, TrackRunTypeEnum.Inserted);
151
- compInfo.offset = 0;
152
- compInfo.element = newInput;
153
- this.inputTextGroup(newInput, data);
154
- return;
155
- } else {
156
- const {
157
- trackElement,
158
- newTextGroup
159
- } = this.createTextTrackElement(startControl, null, TrackRunTypeEnum.Inserted);
160
- this.insertElement(startControl, startOffset, [trackElement])
161
- compInfo.offset = 0;
162
- compInfo.element = newTextGroup;
163
- this.inputTextGroup(newTextGroup, data);
164
- return;
165
- }
166
- }
167
-
168
-
169
- /**
170
- * 创建新的留痕块,并返回留痕块输入定位文本
171
- * @param startControl
172
- * @param startOffset
173
- * @param trackType
174
- * @returns
175
- */
176
- createNewTrackInput(startControl: LeafElement, startOffset: number, trackType: TrackRunTypeEnum): TextGroupElement {
177
- const textProps = this.getDefaultTextProps(startControl, startOffset);
178
- const currTrackEle = startControl.parent as TrackRunElement;
179
- if (startControl instanceof TextGroupElement && startOffset > 0 && startOffset < startControl.textMeasures.length) {
180
- const splitText = startControl.spliceText(startOffset, startControl.textMeasures.length, true) as TextGroupElement;
181
- startControl.parent.addChild(splitText, startControl.getIndex() + 1);
182
- startOffset = startControl.textMeasures.length;
183
- }
184
- startOffset = startOffset > 0 ? 1 : 0;
185
- const index = startControl.getIndex() + startOffset;
186
- //切割留痕块
187
- if (index > 0 && index < currTrackEle.length) {
188
- const splitTrack = currTrackEle.split(startControl.getIndex() + startOffset) as TrackRunElement;
189
- currTrackEle.parent.addChild(splitTrack, currTrackEle.getIndex() + 1);
190
- const { trackElement, newTextGroup } = this.createTextTrackElement(startControl, textProps, trackType);
191
- currTrackEle.parent.addChild(trackElement, currTrackEle.getIndex() + 1);
192
- return newTextGroup;
193
- } else {
194
- const { trackElement, newTextGroup } = this.createTextTrackElement(startControl, textProps, trackType);
195
- currTrackEle.parent.addChild(trackElement, currTrackEle.getIndex() + (index === 0 ? 0 : 1));
196
- return newTextGroup;
197
- }
198
- }
199
-
200
- /**
201
- * 获取当前输入节点的文本属性
202
- * @param startControl
203
- * @returns
204
- */
205
- getDefaultTextProps(startControl: LeafElement, offset: number): TextProps {
206
- const para = ElementUtil.getParentByType(startControl, ParagraphElement) as ParagraphElement;
207
- let textProps = para.props.textProps;
208
- if (startControl instanceof TextGroupElement) {
209
- textProps = startControl.props;
210
- }
211
- const dataEle = ElementUtil.getDataElement(startControl) as DataElementInlineGroup;
212
- if (dataEle && IsInSideDataElement(startControl, offset)) {
213
- return dataEle.props.valueTextProps;
214
- }
215
- return textProps;
216
- }
217
-
218
- /**
219
- * 当前元素位于留痕区域内,但是当前编辑模式为非留痕模式,需要将当前留痕元素分割开来,插入新普通文本元素对象,并返回
220
- * @param startControl
221
- * @param startOffset
222
- * @returns
223
- */
224
- splitTrackElement(startControl: LeafElement, startOffset: number): TextGroupElement {
225
- if (!(startControl.parent instanceof TrackRunElement) && startControl instanceof TextGroupElement) {
226
- return startControl;
227
- }
228
- const textProps = this.getDefaultTextProps(startControl, startOffset);
229
- const currTrackEle = startControl.parent as TrackRunElement;
230
- if (startControl instanceof TextGroupElement && startOffset > 0 && startOffset < startControl.textMeasures.length) {
231
- const splitText = startControl.spliceText(startOffset, startControl.textMeasures.length, true) as TextGroupElement;
232
- startControl.parent.addChild(splitText, startControl.getIndex() + 1);
233
- startOffset = startControl.textMeasures.length;
234
- }
235
- startOffset = startOffset > 0 ? 1 : 0;
236
- const index = startControl.getIndex() + startOffset;
237
- if (index > 0 && index < currTrackEle.length) {
238
- const splitTrack = currTrackEle.split(startControl.getIndex() + startOffset) as TrackRunElement;
239
- currTrackEle.parent.addChild(splitTrack, currTrackEle.getIndex() + 1);
240
- const newInput = ElementUtil.getNewTextGroup(textProps);
241
- currTrackEle.parent.addChild(newInput, currTrackEle.getIndex() + 1);
242
- return this.splitTrackElement(newInput, 0);
243
- } else {
244
- const newInput = ElementUtil.getNewTextGroup(textProps);
245
- currTrackEle.parent.addChild(newInput, currTrackEle.getIndex() + (index === 0 ? 0 : 1));
246
- return this.splitTrackElement(newInput, 0);
247
- }
248
- }
249
-
250
- /**
251
- * 创建插入(ins-run) 留痕,并且返回留痕的文本元素对象
252
- * @param startControl
253
- * @returns
254
- */
255
- private createTextTrackElement(startControl: Element, textProps: TextProps | null, trackType: TrackRunTypeEnum): { trackElement: TrackRunElement, newTextGroup: TextGroupElement } {
256
- const para = ElementUtil.getParentByType(startControl, ParagraphElement) as ParagraphElement;
257
- const trackElement = this.createTrackElement(trackType);
258
- textProps = textProps || para.props.textProps;
259
- const newTextGroup = ElementUtil.getNewTextGroup(textProps);
260
- newTextGroup.props.color = '#ff4d4f';
261
- trackElement.addChild(newTextGroup);
262
- return {
263
- trackElement,
264
- newTextGroup
265
- }
266
-
267
- }
268
-
269
- private createTrackElement(trackType: TrackRunTypeEnum): TrackRunElement {
270
- const trackElement = new TrackRunElement(trackType);
271
- trackElement.props.userId = this.viewOptions.editUser.id;
272
- trackElement.props.userName = this.viewOptions.editUser.name;
273
- trackElement.props.date = CommonUtil.formatNow('YYYY-MM-DD HH:mm:ss');
274
- trackElement.props.id = nanoid(5);
275
- return trackElement;
276
- }
277
-
278
- private inputTextGroup(text: TextGroupElement, data: InputData): void {
279
- const prevInputData = data.prevInputData || '';
280
- const prevInputDataLength = prevInputData.length;
281
- if (!data.compositionStartInfo) {
282
- throw new Error('compositionStartInfo is null')
283
- }
284
-
285
- const { element, offset } = data.compositionStartInfo;
286
- let startInputOffset = offset;
287
- //startInputOffset -= prevInputDataLength;
288
- if (!(element instanceof TextGroupElement)) {
289
- //当前选中元素位于输入元素是起始还是结束位置,如果位于起始位置,则输入偏移量为0,否则为未变更之前的内容length
290
- if (ElementUtil.getNextSiblingElement(element) === text) {
291
- startInputOffset = 0;
292
- } else {
293
- startInputOffset = text.textMeasures.length - prevInputDataLength;
294
- }
295
- }
296
- text.splice(startInputOffset, prevInputDataLength, data.data);
297
- //输入后撤销,导致文本组内为空
298
- if (!text.text.length) {
299
- this.removeEmptyText(text);
300
- } else {
301
- this.selectionState.resetRange(text, startInputOffset + data.data.length);
302
- }
303
- }
304
-
305
-
306
- /**
307
- * backspace,向前删除
308
- */
309
- onBackspace(evt: KeyboardEvent): void {
310
- const { startControl, startOffset, collapsed } = this.selectionState;
311
- if (!startControl) {
312
- throw new Error('startControl is null')
313
- }
314
- const eventElement = new KeyboradElementEvent(this.docCtx);
315
- eventElement.key = 'backspace';
316
- eventElement.source = startControl;
317
- eventElement.sourceEvent = evt;
318
- eventElement.sourceOffset = startOffset;
319
- const res = DocumentEvent.invokeEvent('BackspaceKey', startControl, eventElement, 'Capture', this.docCtx);
320
- if (res && res.isCancel) {
321
- return;
322
- }
323
- this.docComment.updateComments();
324
- if (collapsed) {
325
- this.onBackspaceElement(startControl, startOffset);
326
- } else {
327
- this.onRangeDelete();
328
- }
329
- }
330
-
331
- /**
332
- * delete,向后删除
333
- * @param evt
334
- */
335
- onDeleteKeyHandler(evt: KeyboardEvent): void {
336
- const { startControl, startOffset, collapsed } = this.selectionState;
337
- const eventElement = new KeyboradElementEvent(this.docCtx);
338
- eventElement.key = 'delete';
339
- eventElement.source = startControl;
340
- eventElement.sourceEvent = evt;
341
- eventElement.sourceOffset = startOffset;
342
- const res = DocumentEvent.invokeEvent('DeleteKey', startControl, eventElement, 'Capture', this.docCtx);
343
- if (res && res.isCancel) {
344
- return;
345
- }
346
- if (collapsed) {
347
- this.onKeyDeleteElement(startControl, startOffset);
348
- } else {
349
- this.onRangeDelete();
350
- }
351
- }
352
-
353
- /**
354
- * 根据选择范围删除
355
- */
356
- private onRangeDelete(): { cursorEle: Element, cursorOffset: number } {
357
- const { selectedRange } = this.selectionState;
358
- if (!selectedRange) {
359
- throw new Error('selectionRange is null')
360
- }
361
- //用于刷新后定位光标
362
- let startPointElement: Element;
363
- let startPointOffset = 0;
364
- if (selectedRange.isFullSelected) {
365
- //某个容器的内容被全部选中
366
- if (selectedRange.target instanceof BlockContainerElement) {
367
- startPointElement = selectedRange.target;
368
- startPointOffset = 0;
369
- }
370
- //内容块被选中,需要向上寻找内容块容器
371
- else if (selectedRange.target instanceof BlockContentElement) {
372
- const parentContainer = ElementUtil.getParent(selectedRange.target, (item) => item instanceof BlockContainerElement) as BlockContainerElement;
373
- if (parentContainer) {
374
- startPointElement = parentContainer;
375
- startPointOffset = 0;
376
- } else {
377
- throw new Error('未能向上寻找到定位的内容块容器')
378
- }
379
- } else {
380
- throw new Error('未知条件区间')
381
- }
382
- } else {
383
- const startRange = RangeUtil.getStartRangeTarget(selectedRange) as SelectionContentRange;
384
- const endRange = RangeUtil.getEndRangeTarget(selectedRange) as SelectionContentRange;
385
- if (startRange.isFullSelected) {
386
- startPointElement = ElementUtil.getRecursionPrevSiblingElement(startRange.target, false, true) as LeafElement;
387
- startPointOffset = -1;
388
- //判断结束选区和开始选区是否在一个段落中,尽量落在同一段落中
389
- if (!startPointElement || ElementUtil.isInSameParagraph(startRange.target, endRange.target)) {
390
- if (!endRange.isFullSelected) {
391
- startPointElement = endRange.target;
392
- startPointOffset = 0;
393
- }
394
- }
395
- } else {
396
- startPointElement = startRange.target as LeafElement;
397
- startPointOffset = startRange.startOffset;
398
- }
399
- }
400
- if (this.viewOptions.docMode === DocMode.FormEdit) {
401
- this.deleteRangeInFormEdit(selectedRange)
402
- } else {
403
- this.deleteRange(selectedRange);
404
- }
405
- this.selectionState.resetRange(startPointElement, startPointOffset);
406
- return { cursorEle: startPointElement, cursorOffset: startPointOffset };
407
- }
408
-
409
- /**
410
- * backspace删除
411
- * @param control
412
- * @param offset
413
- * @returns
414
- */
415
- private onBackspaceElement(control: LeafElement, offset: number): void {
416
- this.selectionState.clear();
417
- if (offset === 0) {
418
- const prevEle = ElementUtil.getRecursionPrevSiblingElement(control, false, true);
419
- if (!prevEle) {
420
- this.selectionState.resetRange(control, 0);
421
- return;
422
- }
423
- if (ElementUtil.isInSameParagraph(control, prevEle)) {
424
- if (ElementUtil.getPrevSiblingElement(control) === prevEle) {
425
- this.onBackspaceElement(prevEle, ElementUtil.getElementEndOffset(prevEle));
426
- } else {
427
- this.selectionState.resetRange(prevEle, -1);
428
- }
429
- } else {
430
- //需要判断是否是兄弟段落,兄弟段落,需要合并
431
- const prevPara = ElementUtil.getParentByType(prevEle, ParagraphElement) as ParagraphElement;
432
- const currPara = ElementUtil.getParentByType(control, ParagraphElement) as ParagraphElement;
433
- //表明是紧挨着的两个段落,要进行段落合并
434
- if (ElementUtil.getPrevSiblingElement(currPara) === prevPara) {
435
- if (this.selectionState.enableTrackChanges) {
436
- this.selectionState.resetRange(prevEle, -1);
437
- return;
438
- }
439
- this.combineParagraph(prevPara, currPara, control);
440
- } else {
441
- //不是紧挨着的段落,则前一个段落是位于另一个容器里,例如:处于单元格内的段落
442
- //则不向前定位
443
- this.selectionState.resetRange(control, offset)
444
- }
445
- }
446
- } else {
447
- if (control instanceof TextGroupElement) {
448
- this.onDeleteText(control, offset - 1, 1);
449
- if (!control.textMeasures.length) {
450
- this.removeEmptyText(control);
451
- } else {
452
- this.selectionState.resetRange(control, offset - 1);
453
- }
454
- } else {
455
- if (control.parent instanceof InlineGroupInputElement && control instanceof DataDecorateElement) {
456
- const dataEle = control.parent;
457
- //空数据元,并且当前光标处于数据元开始位置
458
- if (this.canDeleteInlineGroup(dataEle)) {
459
- this.setCurosrForDeleteAction(dataEle);
460
- dataEle.remove();
461
- return;
462
- }
463
- if (control.isPrefix && this.viewOptions.docMode === DocMode.FormEdit) {
464
- if (this.jumpToPrevDataElement(dataEle)) {
465
- return;
466
- }
467
- }
468
- }
469
- if (control.isDecorate) {
470
- this.onBackspaceElement(control, 0);
471
- return;
472
- }
473
- this.removeElement(control);
474
- }
475
- }
476
- }
477
-
478
- /**
479
- * 跳到上一个数据元中
480
- * @param currEle
481
- */
482
- private jumpToPrevDataElement(currEle: InlineGroupInputElement): boolean {
483
- if (this.viewOptions.docMode !== DocMode.FormEdit) {
484
- return false;
485
- }
486
- const prevEle = ElementUtil.getPrevDataElement(this.docCtx, currEle as DataElementInlineGroup);
487
- if (!prevEle) {
488
- return false;
489
- }
490
- if (prevEle) {
491
- this.selectionState.resetRange(prevEle.endDecorate, 0);
492
- return true;
493
- }
494
- return false;
495
- }
496
-
497
- /**
498
- * delete删除
499
- * @param control
500
- * @param offset
501
- * @returns
502
- */
503
- private onKeyDeleteElement(control: LeafElement, offset: number): void {
504
- this.selectionState.clear();
505
- if (offset === ElementUtil.getElementEndOffset(control)) {
506
- const nextEle = ElementUtil.getRecursionNextSiblingElement(control, false, true);
507
- if (!nextEle) {
508
- this.selectionState.resetRange(control, -1);
509
- return;
510
- }
511
- if (ElementUtil.isInSameParagraph(control, nextEle)) {
512
- if (ElementUtil.getNextSiblingElement(control) === nextEle) {
513
- this.onKeyDeleteElement(nextEle, 0);
514
- } else {
515
- this.selectionState.resetRange(nextEle, 0);
516
- }
517
- } else {
518
- //需要判断是否是兄弟段落,兄弟段落,需要合并
519
- const nextPara = ElementUtil.getParentByType(nextEle, ParagraphElement) as ParagraphElement;
520
- const currPara = ElementUtil.getParentByType(control, ParagraphElement) as ParagraphElement;
521
- //表明是紧挨着的两个段落,要进行段落合并
522
- if (ElementUtil.getNextSiblingElement(currPara) === nextPara) {
523
- if (this.selectionState.enableTrackChanges) {
524
- this.selectionState.resetRange(nextEle, 0);
525
- return;
526
- }
527
- this.combineParagraph(nextPara, currPara, control);
528
- } else {
529
- //不是紧挨着的段落,则前一个段落是位于另一个容器里,例如:处于单元格内的段落
530
- //则不向前定位
531
- this.selectionState.resetRange(control, offset)
532
- }
533
- }
534
- } else {
535
- if (control instanceof TextGroupElement) {
536
- this.onDeleteText(control, offset, 1);
537
- if (!control.textMeasures.length) {
538
- this.removeEmptyText(control);
539
- } else {
540
- this.selectionState.resetRange(control, offset);
541
- }
542
- } else {
543
- if (control.parent instanceof DataElementInlineGroup && control instanceof DataDecorateElement) {
544
- const dataEle = control.parent as DataElementInlineGroup;
545
- //空数据元,并且当前光标处于数据元开始位置
546
- if (control.isPrefix) {
547
- if (this.canDeleteInlineGroup(dataEle)) {
548
- this.setCurosrForDeleteAction(dataEle);
549
- dataEle.remove();
550
- } else {
551
- this.selectionState.resetRange(control, -1);
552
- }
553
- return;
554
- } else if (!control.isPrefix && dataEle.length === 2) {
555
- this.selectionState.resetRange(dataEle.endDecorate, -1);
556
- return;
557
- }
558
- }
559
- if (control.isDecorate) {
560
- //this.onKeyDeleteElement(control, -1);
561
- return;
562
- }
563
- this.removeElement(control);
564
- }
565
- }
566
- }
567
-
568
- /**
569
- * 判断是否可以删除数据组
570
- * @param dataEle
571
- * @private
572
- */
573
- private canDeleteInlineGroup(dataEle: InlineGroupInputElement): boolean {
574
- if (this.viewOptions.docMode === DocMode.FormEdit) {
575
- return false;
576
- }
577
- return dataEle.length === 2;
578
- }
579
-
580
- private onDeleteText(text: TextGroupElement, offset: number, len: number): void {
581
- if (this.selectionState.enableTrackChanges) {
582
- this.updateDeletedTrackText(text, offset, len)
583
- } else {
584
- text.splice(offset, len)
585
- }
586
- }
587
-
588
- private onDeleteItem(item: LeafElement): void {
589
- if (this.selectionState.enableTrackChanges) {
590
- //删除符号不进行留痕
591
- if (item.type === 'psym') {
592
- return
593
- }
594
- this.onTrackDeleteElement(item);
595
- } else {
596
- item.remove();
597
- item.destroy();
598
- }
599
- }
600
-
601
-
602
- /**
603
- * 当前元素是否在留痕元素内
604
- * @param target
605
- * @param trackType
606
- * @returns
607
- */
608
- private isInCurrentUserTrack(target: Element, trackType: TrackRunTypeEnum): boolean {
609
- if (target.parent instanceof TrackRunElement && target.parent.type === trackType && target.parent.props.userId === this.viewOptions.editUser.id) {
610
- return true;
611
- }
612
- return false;
613
- }
614
-
615
- private isInTrackElement(target: Element, trackType: TrackRunTypeEnum): boolean {
616
- if (target.parent instanceof TrackRunElement && target.parent.type === trackType) {
617
- return true;
618
- }
619
- return false;
620
- }
621
-
622
-
623
- /**
624
- * 留痕除文本以外的其他元素
625
- * @param control
626
- */
627
- private onTrackDeleteElement(target: LeafElement): void {
628
- const parent = target.parent;
629
- if (this.isInTrackElement(target, TrackRunTypeEnum.Deleted)) {
630
- return;
631
- }
632
- //当前用户增加的内容,内容直接删除不需要留痕
633
- if (this.isInCurrentUserTrack(target, TrackRunTypeEnum.Inserted)) {
634
- target.remove();
635
- this.removeEmtpyInlineBlock(parent);
636
- return;
637
- }
638
- //target.remove();
639
- const trackEle = this.getNextTrackElement(target, TrackRunTypeEnum.Deleted);
640
- trackEle.addChild(target.clone(true), 0);
641
- target.remove();
642
- this.removeEmtpyInlineBlock(parent);
643
- }
644
-
645
- /**
646
- * 更新文本删除留痕
647
- */
648
- private updateDeletedTrackText(target: TextGroupElement, offset: number, len: number): void {
649
- if (this.isInTrackElement(target, TrackRunTypeEnum.Deleted)) {
650
- return;
651
- }
652
- //当前用户增加的内容,当前用户删除时不需要留痕
653
- if (this.isInCurrentUserTrack(target, TrackRunTypeEnum.Inserted)) {
654
- target.splice(offset, len);
655
- return;
656
- }
657
- //全部被删除
658
- if (offset === 0 && len === target.textMeasures.length) {
659
- const trackInputText = this.getNextTrackInputElement(target, TrackRunTypeEnum.Deleted);
660
- trackInputText.text = target.text + trackInputText.text;
661
- target.splice(0, target.textMeasures.length);
662
- //target.remove();
663
- return;
664
- }
665
- const { leftElement } = this.splitText(target, offset + len);
666
- target = leftElement as never;
667
- let trackText: TextGroupElement = this.getNextTrackInputElement(target, TrackRunTypeEnum.Deleted);
668
- const spText = target.spliceText(target.textMeasures.length - len, target.textMeasures.length, true);
669
- trackText.splice(0, 0, spText?.text);
670
- }
671
-
672
-
673
- private getNextTrackInputElement(target: Element, trackType: TrackRunTypeEnum): TextGroupElement {
674
- const trackElement = ElementUtil.getNextSiblingTrackElement(target, trackType, this.viewOptions.editUser.id)
675
- if (trackElement) {
676
- const firstEle = trackElement.getChild(0);
677
- if (firstEle && firstEle instanceof TextGroupElement) {
678
- return firstEle;
679
- } else {
680
- const newInput = new TextGroupElement();
681
- trackElement.addChild(newInput, 0);
682
- target.props.clone(newInput.props);
683
- return newInput;
684
- }
685
- } else {
686
- const {
687
- trackElement,
688
- newTextGroup
689
- } = this.createTextTrackElement(target, target.props, TrackRunTypeEnum.Deleted);
690
- target.parent.addChild(trackElement, target.getIndex() + 1);
691
- return newTextGroup;
692
- }
693
- }
694
-
695
-
696
- private getNextTrackElement(target: Element, trackType: TrackRunTypeEnum): TrackRunElement {
697
- let trackElement = ElementUtil.getNextSiblingTrackElement(target, trackType, this.viewOptions.editUser.id)
698
- if (!trackElement) {
699
- trackElement = this.createTrackElement(trackType);
700
- target.parent.addChild(trackElement, target.getIndex() + 1);
701
- }
702
- return trackElement;
703
- }
704
-
705
-
706
- /**
707
- * 删除元素并定位光标
708
- * @param control
709
- * @returns
710
- */
711
- private removeElement(control: LeafElement): void {
712
- const prevEle = ElementUtil.getRecursionPrevSiblingElement(control, false, true);
713
- if (!prevEle) {
714
- const nextEle = ElementUtil.getRecursionNextSiblingElement(control, true, true);
715
- if (nextEle) {
716
- this.selectionState.resetRange(nextEle, 0);
717
- control.remove();
718
- return;
719
- }
720
- return;
721
- }
722
- if (ElementUtil.isInSameParagraph(control, prevEle)) {
723
- this.selectionState.resetRange(prevEle, -1);
724
- control.remove();
725
- return;
726
- } else {
727
- const nextEle = ElementUtil.getRecursionNextSiblingElement(control, true, true);
728
- if (nextEle && ElementUtil.getPrevSiblingElement(nextEle) === control) {
729
- this.selectionState.resetRange(nextEle, 0);
730
- control.remove();
731
- return;
732
- } else {
733
- this.selectionState.resetRange(prevEle, -1);
734
- control.remove();
735
- return;
736
- }
737
- }
738
- }
739
-
740
-
741
- /**
742
- * 回车事件
743
- */
744
- onEnter(): void {
745
- const { startControl } = this.selectionState;
746
- const paragraph = ElementUtil.getParentByType(startControl, ParagraphElement) as ParagraphElement;
747
- const breakPara = this.splitCurrentParagraph();
748
- //选中的是一个元素
749
- if (breakPara === paragraph) {
750
- const clonePara = paragraph.clone(false);
751
- breakPara.parent.addChild(clonePara, breakPara.getIndex());
752
- }
753
- this.selectionState.resetRange(breakPara, 0);
754
-
755
- }
756
-
757
- /**
758
- * 插入表格
759
- * @param tb
760
- * @returns
761
- */
762
- insertTable(tb: TableElement): void {
763
- const breakPara = this.splitCurrentParagraph();
764
- breakPara.parent.addChild(tb, breakPara.getIndex());
765
- this.selectionState.resetRange(tb, 0);
766
- }
767
-
768
- /**
769
- * 分割当前段落用于插入表格或者粘贴的内容
770
- * @param insertItems 分割后插入的内容,内容需要是block或者表格对象
771
- */
772
- private splitCurrentParagraph(): ParagraphElement {
773
- const { startControl, startOffset } = this.selectionState;
774
- const paragraph = ElementUtil.getParentByType(startControl, ParagraphElement) as ParagraphElement;
775
- const paraContainer = paragraph.parent;
776
- //如果选中的是段落第一个元素
777
- const firstLeaf = ElementUtil.getFirstLeafElement(paragraph);
778
- if ((startControl === firstLeaf && startOffset === 0) || (startControl === firstLeaf && startControl instanceof PSymbolElement)) {
779
- //this.selectionState.resetRange(paragraph, 0);
780
- return paragraph;
781
- }
782
- const last = ElementUtil.getLastLeafElement(paragraph) as LeafElement;
783
- const selectedParaRange = RangeUtil.getSelctionRange(startControl, startOffset, last, 1, paragraph);
784
- selectedParaRange.isFullSelected = false;
785
- const breakPara = ElementUtil.cloneRange(selectedParaRange, true) as ParagraphElement;
786
- ElementUtil.fixParagraphContent(paragraph);
787
- ElementUtil.fixParagraphContent(breakPara);
788
- paraContainer.addChild(breakPara, paragraph.getIndex() + 1);
789
- //paraContainer.addChild(tb, breakPara.getIndex());
790
- //this.selectionState.resetRange(breakPara, 0);
791
- return breakPara;
792
- }
793
-
794
- /**
795
- * 合并段落
796
- */
797
- combineParagraph(prevPara: ParagraphElement, currPara: ParagraphElement, currElement: Element): void {
798
- const prevParaLength = prevPara.length;
799
- for (let i = 0; i < currPara.length; i++) {
800
- const child = currPara.getChild(i).clone(true);
801
- prevPara.addChild(child);
802
- }
803
- //currPara.remove();
804
- const currParaContainer = currPara.parent;
805
- currPara.destroy();
806
- currParaContainer.removeChild(currPara);
807
- this.selectionState.resetRange(prevPara.getChild(prevParaLength), 0);
808
- }
809
-
810
- /**
811
- * 删除选中的区域内容
812
- * @param range
813
- */
814
- deleteRange(range: SelectionContentRange): void {
815
- const { selectedChildren } = range;
816
- for (let i = selectedChildren.length - 1; i >= 0; i--) {
817
- const childRange = selectedChildren[i];
818
- const { target: childTarget, isFullSelected: childFullSelected } = childRange;
819
- if (childTarget instanceof LeafElement && !childTarget.isDecorate) {
820
- if (childFullSelected) {
821
- this.onDeleteItem(childTarget);
822
- } else if (childTarget instanceof TextGroupElement) {
823
- const { startOffset, endOffset } = childRange;
824
- this.onDeleteText(childTarget, startOffset, endOffset - startOffset);
825
- }
826
- } else if (childTarget instanceof BranchElement) {
827
- //留痕模式
828
- if (this.selectionState.enableTrackChanges) {
829
- this.deleteRange(childRange);
830
- } else {
831
- //表格全选状态时,执行删除操作
832
- if (childTarget instanceof TableElement && childFullSelected) {
833
- childTarget.remove();
834
- childTarget.destroy();
835
- }
836
- //段落全选状态时,执行删除操作
837
- else if (childTarget instanceof BlockContentElement && childFullSelected) {
838
- childTarget.remove();
839
- childTarget.destroy();
840
- } else if (childTarget instanceof InlineGroupElement && childFullSelected) {
841
- childTarget.remove();
842
- childTarget.destroy();
843
- } else {
844
- this.deleteRange(childRange);
845
- }
846
- }
847
- }
848
- }
849
- }
850
-
851
-
852
- /**
853
- * 表单区域删除处理
854
- * @param range
855
- * @returns
856
- */
857
- private deleteRangeInFormEdit(range: SelectionContentRange): void {
858
- const dataElement = ElementUtil.getDataElement(range.target);
859
- //在数据元内删除,调用普通的删除处理
860
- if (dataElement) {
861
- this.deleteRange(range);
862
- return;
863
- }
864
- //在数据元外删除
865
- else {
866
- this.loopForDelDataEleRange(range);
867
- }
868
- }
869
-
870
- /**
871
- * 表单模式:删除选中的区域内容
872
- */
873
- private loopForDelDataEleRange(range: SelectionContentRange): void {
874
- const { selectedChildren } = range;
875
- for (let i = selectedChildren.length - 1; i >= 0; i--) {
876
- const childRange = selectedChildren[i];
877
- const { target: childTarget } = childRange;
878
- if (childTarget instanceof BranchElement) {
879
- if (childTarget instanceof DataElementInlineGroup) {
880
- const dataEleProps = childTarget.props as DataEleBaseProps;
881
- //数据元可编辑
882
- if (dataEleProps.editable) {
883
- this.deleteRange(childRange);
884
- }
885
- } else {
886
- this.loopForDelDataEleRange(childRange)
887
- }
888
- }
889
- }
890
- }
891
-
892
-
893
- /**
894
- * 向目标移动元素
895
- * @param sourceElement
896
- * @param moveElement
897
- */
898
- moveElement(targetElement: Element, targetOffset: number, moveElement: Element, moveOffset: number, ss: SelectionState): void {
899
- moveElement.remove();
900
- if (targetElement instanceof TextGroupElement) {
901
- const { leftElement, rightElement } = this.splitText(targetElement, targetOffset);
902
- if (leftElement) {
903
- leftElement.parent.addChild(moveElement, leftElement.getIndex() + 1)
904
- } else if (rightElement) {
905
- rightElement.parent.addChild(moveElement, rightElement.getIndex())
906
- }
907
- } else {
908
- targetElement.parent.addChild(moveElement, targetElement.getIndex() + targetOffset);
909
- }
910
- ss.resetRange(moveElement, moveOffset);
911
- }
912
-
913
- /**
914
- * 向指定的目标插入元素
915
- * @param targetElement
916
- * @param targetOffset
917
- * @param destEleArray
918
- */
919
- insertElement(targetElement: Element, targetOffset: number, destEleArray: Array<Element>): Element | null {
920
- let lastEle!: Element | null;
921
- if (targetElement instanceof TextGroupElement) {
922
- const { leftElement, rightElement } = this.splitText(targetElement, targetOffset);
923
- if (leftElement) {
924
- for (let i = 0; i < destEleArray.length; i++) {
925
- lastEle = destEleArray[i];
926
- leftElement.parent.addChild(lastEle, leftElement.getIndex() + 1 + i);
927
- }
928
- } else if (rightElement) {
929
- for (let i = 0; i < destEleArray.length; i++) {
930
- lastEle = destEleArray[i]
931
- rightElement.parent.addChild(lastEle, rightElement.getIndex());
932
- }
933
- }
934
- } else {
935
- for (let i = 0; i < destEleArray.length; i++) {
936
- lastEle = destEleArray[i]
937
- targetElement.parent.addChild(lastEle, targetElement.getIndex() + targetOffset);
938
- }
939
- }
940
- return lastEle;
941
- }
942
-
943
-
944
- /**
945
- * 根据开始位置和结束位置,将字符切割成指定的区间
946
- * @param splitTextUnit
947
- * @param start
948
- * @param end
949
- * @returns
950
- */
951
- static splitTextGroupByRange(text: TextGroupElement, start: number, end: number): TextGroupElement | null {
952
- end = end === -1 ? text.textMeasures.length : end;
953
- if (start === end) {
954
- return null;
955
- }
956
- if (start === 0 && end === text.textMeasures.length) {
957
- return text;
958
- }
959
- if (start === text.textMeasures.length) {
960
- return null;
961
- }
962
- let lastTextGroup = text.spliceText(end, -1, true);
963
- let middleTextGroup = text.spliceText(start, -1, true);
964
- if (lastTextGroup) {
965
- text.parent.addChild(lastTextGroup, text.getIndex() + 1);
966
- }
967
- if (!middleTextGroup) {
968
- throw new Error('middleText is null');
969
- }
970
- text.parent.addChild(middleTextGroup, text.getIndex() + 1);
971
-
972
- if (text.textMeasures.length === 0) {
973
- text.remove();
974
- text.destroy();
975
- }
976
- return middleTextGroup;
977
- }
978
-
979
- splitText(text: TextGroupElement, offset: number): { leftElement: TextGroupElement | null, rightElement: TextGroupElement | null } {
980
- offset = offset == -1 ? text.textMeasures.length : offset;
981
- if (offset === text.textMeasures.length) {
982
- return {
983
- leftElement: text,
984
- rightElement: null
985
- }
986
- }
987
- if (offset === 0) {
988
- return {
989
- leftElement: null,
990
- rightElement: text
991
- }
992
- }
993
- const rightText = text.spliceText(offset, -1, true);
994
- if (rightText) {
995
- text.parent.addChild(rightText, text.getIndex() + 1);
996
- }
997
- let leftText: TextGroupElement | null = text;
998
- if (text.textMeasures.length === 0) {
999
- text.remove();
1000
- leftText = null;
1001
- }
1002
- return {
1003
- leftElement: leftText,
1004
- rightElement: rightText
1005
- }
1006
- }
1007
-
1008
- /**
1009
- * 设置选中的文本样式
1010
- * @param ss
1011
- * @param setterFunc
1012
- * @returns
1013
- */
1014
- static setTextStyle(ss: SelectionState, setterFunc: (tp: TextProps) => void): void {
1015
- const range = ss.selectedRange;
1016
- if (!range || ss.collapsed) {
1017
- return;
1018
- }
1019
- const newSelectionRange = new SelectionRange();
1020
- const startRange = ElementUtil.getFirstSelectedRange(range);
1021
- const endRange = ElementUtil.getLastSelectedRange(range);
1022
- this.recursionSetRangeTextStyle(range, setterFunc);
1023
- if (startRange === endRange) {
1024
- if (startRange.isFullSelected) {
1025
- newSelectionRange.setStart(startRange.target, 0);
1026
- newSelectionRange.setEnd(startRange.target, -1);
1027
- }
1028
- if (startRange.target instanceof TextGroupElement) {
1029
- const startSelectedOffset = ss.startOffset;
1030
- const endSelectedOffset = ss.endOffset;
1031
- const middleElement = this.splitTextGroupByRange(startRange.target, startSelectedOffset, endSelectedOffset);
1032
- if (middleElement) {
1033
- setterFunc(middleElement.props);
1034
- newSelectionRange.setStart(middleElement, 0);
1035
- newSelectionRange.setEnd(middleElement, -1);
1036
- }
1037
- }
1038
- } else {
1039
- if (startRange.isFullSelected) {
1040
- newSelectionRange.setStart(startRange.target, 0);
1041
- } else {
1042
- if (startRange.target instanceof TextGroupElement) {
1043
- const middleElement = this.splitTextGroupByRange(startRange.target, startRange.startOffset, -1);
1044
- if (middleElement) {
1045
- setterFunc(middleElement.props);
1046
- newSelectionRange.setStart(middleElement, 0);
1047
- } else {
1048
- newSelectionRange.setStart(startRange.target, 0);
1049
- }
1050
- } else {
1051
- newSelectionRange.setStart(startRange.target, startRange.startOffset);
1052
- }
1053
- }
1054
- if (endRange.isFullSelected) {
1055
- newSelectionRange.setEnd(endRange.target, -1);
1056
- } else {
1057
- if (endRange.target instanceof TextGroupElement) {
1058
- const middleElement = this.splitTextGroupByRange(endRange.target, 0, endRange.endOffset);
1059
- if (middleElement) {
1060
- setterFunc(middleElement.props);
1061
- newSelectionRange.setEnd(middleElement, -1);
1062
- } else {
1063
- newSelectionRange.setStart(endRange.target, 0);
1064
- }
1065
-
1066
- } else {
1067
- newSelectionRange.setEnd(endRange.target, endRange.endOffset);
1068
- }
1069
- }
1070
- }
1071
- ss.addRange(newSelectionRange);
1072
- }
1073
-
1074
- private static recursionSetRangeTextStyle(range: SelectionContentRange, setterFunc: (tp: TextProps) => void): void {
1075
- RangeUtil.recursionTraversalRangeHandler(range, (itemRange) => {
1076
- if (itemRange.target instanceof TextGroupElement && itemRange.isFullSelected) {
1077
- setterFunc(itemRange.target.props)
1078
- }
1079
- })
1080
- }
1081
-
1082
-
1083
- static setParaAlign(ss: SelectionState, setterFunc: (tp: ParagraphProps) => void): void {
1084
- if (ss.collapsed && ss.startControl) {
1085
- const para = ElementUtil.getParentByType(ss.startControl, ParagraphElement);
1086
- if (para) {
1087
- setterFunc(para.props);
1088
- }
1089
- } else {
1090
- const range = ss.selectedRange;
1091
- if (!range) {
1092
- return;
1093
- }
1094
- RangeUtil.recursionTraversalRangeHandler(range, (itemRange) => {
1095
- if (itemRange.target instanceof ParagraphElement) {
1096
- setterFunc(itemRange.target.props);
1097
- }
1098
- })
1099
- }
1100
-
1101
- }
1102
-
1103
-
1104
- /**
1105
- * 复制
1106
- * @param evt
1107
- * @returns
1108
- */
1109
- onCopy(evt: ClipboardEvent): void {
1110
- evt.preventDefault();
1111
- const copySerializeStr = ElementSerialize.getSelectedJSON(this.selectionState, this.viewOptions);
1112
- if (!copySerializeStr) {
1113
- return;
1114
- }
1115
- evt.clipboardData?.setData('doc/plain', copySerializeStr);
1116
- const copyStr = ElementSerialize.getSelectedText(this.selectionState, this.viewOptions);
1117
- evt.clipboardData?.setData('text/plain', copyStr);
1118
- }
1119
-
1120
- /**
1121
- * 剪切
1122
- * @param evt
1123
- */
1124
- onCut(evt: ClipboardEvent): void {
1125
- this.onCopy(evt);
1126
- this.onRangeDelete();
1127
- }
1128
-
1129
- /**
1130
- * 粘贴
1131
- * @param evt
1132
- * @returns
1133
- */
1134
- onPaste(evt: ClipboardEvent): void {
1135
- evt.preventDefault();
1136
- let pasteText = evt.clipboardData?.getData('text/plain');
1137
- const pasteData = evt.clipboardData?.getData('doc/plain');
1138
- if (!pasteData) {
1139
- if (pasteText) {
1140
- this.pastePlainText(pasteText);
1141
- }
1142
- return;
1143
- }
1144
- const pasteElement = this.eleReader.readElement(JSON.parse(pasteData));
1145
- if (!pasteElement) {
1146
- console.log('粘贴反序列化数据失败', pasteData);
1147
- return;
1148
- }
1149
- const { collapsed } = this.selectionState;
1150
- let { startControl, startOffset } = this.selectionState;
1151
- if (!collapsed) {
1152
- //TODO:如果一个容器内的元素被全部删除,则返回 null
1153
- // const { cursorEle, cursorOffset } = this.onRangeDelete();
1154
- // startControl = cursorEle;
1155
- // startOffset = cursorOffset;
1156
- }
1157
- if (!startControl) {
1158
- return;
1159
- }
1160
- //表单模式:如果复制的是单格式的文本,需要序列化为纯文本处理
1161
- if (this.viewOptions.docMode === DocMode.FormEdit) {
1162
- const pasteString = ElementSerialize.serializeString(pasteElement, { all: false });
1163
- if (pasteString) {
1164
- this.pastePlainText(pasteString);
1165
- }
1166
- return;
1167
- }
1168
- if (pasteElement instanceof ParagraphElement || pasteElement instanceof InlineGroupElement) {
1169
- const children: Array<Element> = [];
1170
- if (pasteElement instanceof ParagraphElement) {
1171
- children.push(...ElementUtil.getChildrenElements(pasteElement));
1172
- } else if (pasteElement instanceof InlineGroupElement) {
1173
- children.push(pasteElement);
1174
- }
1175
- if (!children.length) {
1176
- throw new Error('段落子元素为空');
1177
- }
1178
- const lastEle = this.insertElement(startControl, startOffset, children) as Element;
1179
- this.selectionState.resetRange(lastEle, -1);
1180
- return;
1181
- }
1182
- console.log('粘贴:' + pasteData);
1183
- }
1184
-
1185
- insertSoftBr(): void {
1186
- let { startControl, startOffset } = this.selectionState;
1187
- const lastEle = this.insertElement(startControl, startOffset, [new BreakElement()]) as Element;
1188
- const focusEle = ElementUtil.getNextSiblingElement(lastEle);
1189
- if (focusEle) {
1190
- this.selectionState.resetRange(focusEle, 0);
1191
- }
1192
-
1193
- }
1194
-
1195
- /**
1196
- * 处理黏贴的纯文本
1197
- * @param text
1198
- */
1199
- private pastePlainText(text: string): void {
1200
- const textItems = text.split(/\r?\n/);
1201
- const { startControl, startOffset } = this.selectionState;
1202
- if (this.viewOptions.docMode === DocMode.FormEdit || textItems.length === 1 || IsInSideInlineGroupInputElement(startControl, startOffset)) {
1203
- text = text.replace(/[\n\r]/g, '');
1204
- this.newInput({
1205
- data: text,
1206
- compositionStartInfo: {
1207
- element: startControl,
1208
- offset: startOffset
1209
- }
1210
- })
1211
- } else {
1212
- const breakPara = this.splitCurrentParagraph();
1213
- for (let i = 0; i < textItems.length; i++) {
1214
- const newPara = breakPara.clone(false) as ParagraphElement;
1215
- const inputTextProps = newPara.props.textProps;
1216
- const newTextEle = ElementUtil.getNewTextGroup(inputTextProps);
1217
- newTextEle.text = textItems[i];
1218
- newPara.addChild(newTextEle, 0);
1219
- breakPara.parent.addChild(newPara, breakPara.getIndex());
1220
- }
1221
- this.selectionState.resetRange(breakPara, 0);
1222
- }
1223
- }
1224
-
1225
- /**
1226
- * 设置当前段落项目符号类型
1227
- */
1228
- setParagraphNumberType(): void {
1229
- const { startControl } = this.selectionState;
1230
- if (!startControl) {
1231
- return;
1232
- }
1233
- const para = ElementUtil.getParentByType(startControl, ParagraphElement) as ParagraphElement;
1234
- if (para.props.numberType >= 0) {
1235
- para.props.numberType = -1;
1236
- para.props.indent = 0;
1237
- } else {
1238
- para.props.numberType = 0;
1239
- para.props.indent = 15;
1240
- }
1241
- }
1242
-
1243
- /**
1244
- * 插入批注
1245
- */
1246
- insertComment(): void {
1247
- const { startControl, startOffset, endControl, endOffset, collapsed } = this.selectionState;
1248
- if (collapsed || !startControl || !endControl) {
1249
- return;
1250
- }
1251
- const id = nanoid(5);
1252
- const startCommMark = new CommentElement();
1253
- startCommMark.props.id = id;
1254
- startCommMark.props.markType = 'start';
1255
-
1256
- const endCommMark = new CommentElement();
1257
- endCommMark.props.id = id;
1258
- endCommMark.props.markType = 'end';
1259
-
1260
- this.insertElement(endControl, endOffset, [endCommMark])
1261
- this.insertElement(startControl, startOffset, [startCommMark])
1262
-
1263
- const commContent = new CommContentElement();
1264
- commContent.props.id = id;
1265
- commContent.props.createId = this.viewOptions.editUser.id;
1266
- commContent.props.createName = this.viewOptions.editUser.name;
1267
- commContent.props.createDate = new Date();
1268
- const pos = this.docComment.getCommMarkIndex(startCommMark);
1269
- if (pos < 0) {
1270
- throw new Error('获取插入的批注位置不正确');
1271
- }
1272
- this.docCtx.document.commentsContainerElement.addChild(commContent, pos);
1273
- this.selectionState.clear();
1274
-
1275
- this.docComment.afterCommentsChanged();
1276
- }
1277
-
1278
- validate(): boolean {
1279
- const dataEleList = this.docCtx.document.treeFilter(item => item instanceof DataElementInlineGroup) as Array<DataElementInlineGroup>;
1280
- const errorEleList = dataEleList.map(item => ({ error: item.validate(), ele: item })).filter(item => item.error);
1281
- if (!errorEleList.length) {
1282
- return true;
1283
- }
1284
- errorEleList.forEach(item => {
1285
- const id = nanoid(5);
1286
- const startCommMark = new CommentElement();
1287
- startCommMark.props.id = id;
1288
- startCommMark.props.markType = 'start';
1289
-
1290
- const endCommMark = new CommentElement();
1291
- endCommMark.props.id = id;
1292
- endCommMark.props.markType = 'end';
1293
-
1294
- item.ele.addChild(startCommMark, 0);
1295
- item.ele.addChild(endCommMark, item.ele.length)
1296
- const caption = CommonUtil.nullToString(item.ele.props.caption);
1297
- const validateElement = new ValidateElement();
1298
- validateElement.props.title = caption + '验证';
1299
- validateElement.props.id = id;
1300
- validateElement.setContent(item.error);
1301
-
1302
- const pos = this.docComment.getCommMarkIndex(startCommMark);
1303
- this.docCtx.document.commentsContainerElement.addChild(validateElement, pos);
1304
-
1305
-
1306
- })
1307
- this.docCtx.selectionState.clear();
1308
- this.docComment.afterCommentsChanged();
1309
-
1310
- return false;
1311
- }
1312
-
1313
- /**
1314
- * 移除空字符串
1315
- * @param text
1316
- */
1317
- removeEmptyText(text: TextGroupElement): void {
1318
- //const nextLeafElementInPara = ElementUtil.getRecursionNextSiblingElement(text, true, true); getComputedStyle
1319
- this.setCurosrForDeleteAction(text);
1320
- const parent = text.parent;
1321
- text.remove();
1322
- this.removeEmtpyInlineBlock(parent);
1323
- }
1324
-
1325
- setCurosrForDeleteAction(control: Element): void {
1326
- const cursorInfo = this.getCursorElementByDeleteAction(control);
1327
- if (cursorInfo) {
1328
- this.selectionState.resetRange(cursorInfo.ele, cursorInfo.offset);
1329
- } else {
1330
- this.selectionState.clear();
1331
- }
1332
- }
1333
-
1334
- getCursorElementByDeleteAction(control: Element): { ele: LeafElement, offset: number } | null {
1335
- const prevLeafElementInPara = ElementUtil.getRecursionPrevSiblingElement(control, false, true);
1336
- //判断是否为同一段落
1337
- if (prevLeafElementInPara && ElementUtil.isInSameParagraph(prevLeafElementInPara, control)) {
1338
- return {
1339
- ele: prevLeafElementInPara,
1340
- offset: ElementUtil.getElementEndOffset(prevLeafElementInPara)
1341
- }
1342
- }
1343
- //同一段落其他元素
1344
- const nextLeafElementInPara = ElementUtil.getRecursionNextSiblingElement(control, true, true);
1345
- if (nextLeafElementInPara) {
1346
- return {
1347
- ele: nextLeafElementInPara,
1348
- offset: 0
1349
- }
1350
- }
1351
- //上一段落
1352
- if (prevLeafElementInPara) {
1353
- return {
1354
- ele: prevLeafElementInPara,
1355
- offset: prevLeafElementInPara instanceof PSymbolElement ? 0 : ElementUtil.getElementEndOffset(prevLeafElementInPara)
1356
- }
1357
- }
1358
- return null;
1359
- }
1360
-
1361
- /**
1362
- * 移除空行内标签
1363
- * @param ele
1364
- */
1365
- removeEmtpyInlineBlock(ele: Element): void {
1366
- if (ele instanceof InlineGroupElement && ele.length === 0) {
1367
- const parent = ele.parent;
1368
- ele.remove();
1369
- this.removeEmtpyInlineBlock(parent);
1370
- }
1371
- }
1372
-
1373
- /**
1374
- * 插入强制换页符号
1375
- */
1376
- insertPageBreakPara(): void {
1377
- const { startControl } = this.selectionState;
1378
- const currPara = ElementUtil.getParentByType(startControl, ParagraphElement)
1379
- if (!currPara) {
1380
- return;
1381
- }
1382
- if (currPara.parent instanceof DocumentBodyElement) {
1383
- const pageBreak = new ParagraphElement();
1384
- pageBreak.props.pageBreak = true;
1385
- pageBreak.props.textAlign = 'center';
1386
- pageBreak.parent.addChild(pageBreak);
1387
- }
1388
- }
1389
-
1390
-
1391
- }