@trebco/treb 36.1.4 → 37.0.1

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 (552) hide show
  1. package/api-config.json +1 -1
  2. package/build/package.json +119 -0
  3. package/build/treb-base-types/src/api_types.d.ts +11 -0
  4. package/build/treb-base-types/src/api_types.js +22 -0
  5. package/build/treb-base-types/src/api_types.js.map +1 -0
  6. package/build/treb-base-types/src/area-utils.d.ts +9 -0
  7. package/build/treb-base-types/src/area-utils.js +50 -0
  8. package/build/treb-base-types/src/area-utils.js.map +1 -0
  9. package/build/treb-base-types/src/area.d.ts +182 -0
  10. package/build/treb-base-types/src/area.js +715 -0
  11. package/build/treb-base-types/src/area.js.map +1 -0
  12. package/build/treb-base-types/src/basic_types.d.ts +20 -0
  13. package/build/treb-base-types/src/basic_types.js +22 -0
  14. package/build/treb-base-types/src/basic_types.js.map +1 -0
  15. package/build/treb-base-types/src/cell.d.ts +167 -0
  16. package/build/treb-base-types/src/cell.js +432 -0
  17. package/build/treb-base-types/src/cell.js.map +1 -0
  18. package/build/treb-base-types/src/cells.d.ts +251 -0
  19. package/build/treb-base-types/src/cells.js +1136 -0
  20. package/build/treb-base-types/src/cells.js.map +1 -0
  21. package/build/treb-base-types/src/color.d.ts +35 -0
  22. package/build/treb-base-types/src/color.js +162 -0
  23. package/build/treb-base-types/src/color.js.map +1 -0
  24. package/build/treb-base-types/src/dom-utilities.d.ts +70 -0
  25. package/build/treb-base-types/src/dom-utilities.js +144 -0
  26. package/build/treb-base-types/src/dom-utilities.js.map +1 -0
  27. package/build/treb-base-types/src/evaluate-options.d.ts +35 -0
  28. package/build/treb-base-types/src/evaluate-options.js +22 -0
  29. package/build/treb-base-types/src/evaluate-options.js.map +1 -0
  30. package/build/treb-base-types/src/font-stack.d.ts +37 -0
  31. package/build/treb-base-types/src/font-stack.js +93 -0
  32. package/build/treb-base-types/src/font-stack.js.map +1 -0
  33. package/build/treb-base-types/src/gradient.d.ts +18 -0
  34. package/build/treb-base-types/src/gradient.js +86 -0
  35. package/build/treb-base-types/src/gradient.js.map +1 -0
  36. package/build/treb-base-types/src/import.d.ts +48 -0
  37. package/build/treb-base-types/src/import.js +22 -0
  38. package/build/treb-base-types/src/import.js.map +1 -0
  39. package/build/treb-base-types/src/index-standalone.d.ts +6 -0
  40. package/build/treb-base-types/src/index-standalone.js +27 -0
  41. package/build/treb-base-types/src/index-standalone.js.map +1 -0
  42. package/build/treb-base-types/src/index.d.ts +22 -0
  43. package/build/treb-base-types/src/index.js +45 -0
  44. package/build/treb-base-types/src/index.js.map +1 -0
  45. package/build/treb-base-types/src/layout.d.ts +22 -0
  46. package/build/treb-base-types/src/layout.js +22 -0
  47. package/build/treb-base-types/src/layout.js.map +1 -0
  48. package/build/treb-base-types/src/localization.d.ts +37 -0
  49. package/build/treb-base-types/src/localization.js +157 -0
  50. package/build/treb-base-types/src/localization.js.map +1 -0
  51. package/build/treb-base-types/src/rectangle.d.ts +51 -0
  52. package/build/treb-base-types/src/rectangle.js +123 -0
  53. package/build/treb-base-types/src/rectangle.js.map +1 -0
  54. package/build/treb-base-types/src/render_text.d.ts +34 -0
  55. package/build/treb-base-types/src/render_text.js +22 -0
  56. package/build/treb-base-types/src/render_text.js.map +1 -0
  57. package/build/treb-base-types/src/style.d.ts +214 -0
  58. package/build/treb-base-types/src/style.js +373 -0
  59. package/build/treb-base-types/src/style.js.map +1 -0
  60. package/build/treb-base-types/src/table.d.ts +58 -0
  61. package/build/treb-base-types/src/table.js +27 -0
  62. package/build/treb-base-types/src/table.js.map +1 -0
  63. package/build/treb-base-types/src/text_part.d.ts +26 -0
  64. package/build/treb-base-types/src/text_part.js +47 -0
  65. package/build/treb-base-types/src/text_part.js.map +1 -0
  66. package/build/treb-base-types/src/theme.d.ts +120 -0
  67. package/build/treb-base-types/src/theme.js +460 -0
  68. package/build/treb-base-types/src/theme.js.map +1 -0
  69. package/build/treb-base-types/src/union.d.ts +73 -0
  70. package/build/treb-base-types/src/union.js +61 -0
  71. package/build/treb-base-types/src/union.js.map +1 -0
  72. package/build/treb-base-types/src/value-type.d.ts +86 -0
  73. package/build/treb-base-types/src/value-type.js +168 -0
  74. package/build/treb-base-types/src/value-type.js.map +1 -0
  75. package/build/treb-base-types/src/worker-proxy.d.ts +95 -0
  76. package/build/treb-base-types/src/worker-proxy.js +221 -0
  77. package/build/treb-base-types/src/worker-proxy.js.map +1 -0
  78. package/build/treb-calculator/src/calculator.d.ts +249 -0
  79. package/build/treb-calculator/src/calculator.js +2755 -0
  80. package/build/treb-calculator/src/calculator.js.map +1 -0
  81. package/build/treb-calculator/src/complex-math.d.ts +75 -0
  82. package/build/treb-calculator/src/complex-math.js +559 -0
  83. package/build/treb-calculator/src/complex-math.js.map +1 -0
  84. package/build/treb-calculator/src/dag/array-vertex.d.ts +71 -0
  85. package/build/treb-calculator/src/dag/array-vertex.js +156 -0
  86. package/build/treb-calculator/src/dag/array-vertex.js.map +1 -0
  87. package/build/treb-calculator/src/dag/calculation_leaf_vertex.d.ts +48 -0
  88. package/build/treb-calculator/src/dag/calculation_leaf_vertex.js +84 -0
  89. package/build/treb-calculator/src/dag/calculation_leaf_vertex.js.map +1 -0
  90. package/build/treb-calculator/src/dag/graph.d.ts +134 -0
  91. package/build/treb-calculator/src/dag/graph.js +842 -0
  92. package/build/treb-calculator/src/dag/graph.js.map +1 -0
  93. package/build/treb-calculator/src/dag/spreadsheet_vertex.d.ts +58 -0
  94. package/build/treb-calculator/src/dag/spreadsheet_vertex.js +232 -0
  95. package/build/treb-calculator/src/dag/spreadsheet_vertex.js.map +1 -0
  96. package/build/treb-calculator/src/dag/spreadsheet_vertex_base.d.ts +20 -0
  97. package/build/treb-calculator/src/dag/spreadsheet_vertex_base.js +25 -0
  98. package/build/treb-calculator/src/dag/spreadsheet_vertex_base.js.map +1 -0
  99. package/build/treb-calculator/src/dag/state_leaf_vertex.d.ts +43 -0
  100. package/build/treb-calculator/src/dag/state_leaf_vertex.js +81 -0
  101. package/build/treb-calculator/src/dag/state_leaf_vertex.js.map +1 -0
  102. package/build/treb-calculator/src/dag/vertex.d.ts +71 -0
  103. package/build/treb-calculator/src/dag/vertex.js +274 -0
  104. package/build/treb-calculator/src/dag/vertex.js.map +1 -0
  105. package/build/treb-calculator/src/descriptors.d.ts +189 -0
  106. package/build/treb-calculator/src/descriptors.js +22 -0
  107. package/build/treb-calculator/src/descriptors.js.map +1 -0
  108. package/build/treb-calculator/src/expression-calculator.d.ts +127 -0
  109. package/build/treb-calculator/src/expression-calculator.js +1033 -0
  110. package/build/treb-calculator/src/expression-calculator.js.map +1 -0
  111. package/build/treb-calculator/src/function-error.d.ts +35 -0
  112. package/build/treb-calculator/src/function-error.js +85 -0
  113. package/build/treb-calculator/src/function-error.js.map +1 -0
  114. package/build/treb-calculator/src/function-library.d.ts +22 -0
  115. package/build/treb-calculator/src/function-library.js +96 -0
  116. package/build/treb-calculator/src/function-library.js.map +1 -0
  117. package/build/treb-calculator/src/functions/base-functions.d.ts +7 -0
  118. package/build/treb-calculator/src/functions/base-functions.js +2611 -0
  119. package/build/treb-calculator/src/functions/base-functions.js.map +1 -0
  120. package/build/treb-calculator/src/functions/beta.d.ts +17 -0
  121. package/build/treb-calculator/src/functions/beta.js +201 -0
  122. package/build/treb-calculator/src/functions/beta.js.map +1 -0
  123. package/build/treb-calculator/src/functions/checkbox.d.ts +3 -0
  124. package/build/treb-calculator/src/functions/checkbox.js +128 -0
  125. package/build/treb-calculator/src/functions/checkbox.js.map +1 -0
  126. package/build/treb-calculator/src/functions/complex-functions.d.ts +2 -0
  127. package/build/treb-calculator/src/functions/complex-functions.js +217 -0
  128. package/build/treb-calculator/src/functions/complex-functions.js.map +1 -0
  129. package/build/treb-calculator/src/functions/date-utils.d.ts +3 -0
  130. package/build/treb-calculator/src/functions/date-utils.js +59 -0
  131. package/build/treb-calculator/src/functions/date-utils.js.map +1 -0
  132. package/build/treb-calculator/src/functions/finance-functions.d.ts +2 -0
  133. package/build/treb-calculator/src/functions/finance-functions.js +547 -0
  134. package/build/treb-calculator/src/functions/finance-functions.js.map +1 -0
  135. package/build/treb-calculator/src/functions/fp.d.ts +2 -0
  136. package/build/treb-calculator/src/functions/fp.js +463 -0
  137. package/build/treb-calculator/src/functions/fp.js.map +1 -0
  138. package/build/treb-calculator/src/functions/function-utilities.d.ts +2 -0
  139. package/build/treb-calculator/src/functions/function-utilities.js +36 -0
  140. package/build/treb-calculator/src/functions/function-utilities.js.map +1 -0
  141. package/build/treb-calculator/src/functions/gamma.d.ts +20 -0
  142. package/build/treb-calculator/src/functions/gamma.js +142 -0
  143. package/build/treb-calculator/src/functions/gamma.js.map +1 -0
  144. package/build/treb-calculator/src/functions/information-functions.d.ts +2 -0
  145. package/build/treb-calculator/src/functions/information-functions.js +71 -0
  146. package/build/treb-calculator/src/functions/information-functions.js.map +1 -0
  147. package/build/treb-calculator/src/functions/lambda-functions.d.ts +2 -0
  148. package/build/treb-calculator/src/functions/lambda-functions.js +85 -0
  149. package/build/treb-calculator/src/functions/lambda-functions.js.map +1 -0
  150. package/build/treb-calculator/src/functions/matrix-functions.d.ts +2 -0
  151. package/build/treb-calculator/src/functions/matrix-functions.js +144 -0
  152. package/build/treb-calculator/src/functions/matrix-functions.js.map +1 -0
  153. package/build/treb-calculator/src/functions/normal.d.ts +2 -0
  154. package/build/treb-calculator/src/functions/normal.js +32 -0
  155. package/build/treb-calculator/src/functions/normal.js.map +1 -0
  156. package/build/treb-calculator/src/functions/regex-functions.d.ts +2 -0
  157. package/build/treb-calculator/src/functions/regex-functions.js +188 -0
  158. package/build/treb-calculator/src/functions/regex-functions.js.map +1 -0
  159. package/build/treb-calculator/src/functions/sparkline.d.ts +37 -0
  160. package/build/treb-calculator/src/functions/sparkline.js +264 -0
  161. package/build/treb-calculator/src/functions/sparkline.js.map +1 -0
  162. package/build/treb-calculator/src/functions/statistics-functions.d.ts +6 -0
  163. package/build/treb-calculator/src/functions/statistics-functions.js +989 -0
  164. package/build/treb-calculator/src/functions/statistics-functions.js.map +1 -0
  165. package/build/treb-calculator/src/functions/students-t.d.ts +3 -0
  166. package/build/treb-calculator/src/functions/students-t.js +64 -0
  167. package/build/treb-calculator/src/functions/students-t.js.map +1 -0
  168. package/build/treb-calculator/src/functions/text-functions.d.ts +3 -0
  169. package/build/treb-calculator/src/functions/text-functions.js +320 -0
  170. package/build/treb-calculator/src/functions/text-functions.js.map +1 -0
  171. package/build/treb-calculator/src/index.d.ts +2 -0
  172. package/build/treb-calculator/src/index.js +22 -0
  173. package/build/treb-calculator/src/index.js.map +1 -0
  174. package/build/treb-calculator/src/notifier-types.d.ts +26 -0
  175. package/build/treb-calculator/src/notifier-types.js +22 -0
  176. package/build/treb-calculator/src/notifier-types.js.map +1 -0
  177. package/build/treb-calculator/src/primitives.d.ts +15 -0
  178. package/build/treb-calculator/src/primitives.js +398 -0
  179. package/build/treb-calculator/src/primitives.js.map +1 -0
  180. package/build/treb-calculator/src/utilities.d.ts +68 -0
  181. package/build/treb-calculator/src/utilities.js +324 -0
  182. package/build/treb-calculator/src/utilities.js.map +1 -0
  183. package/build/treb-charts/src/chart-functions.d.ts +8 -0
  184. package/build/treb-charts/src/chart-functions.js +209 -0
  185. package/build/treb-charts/src/chart-functions.js.map +1 -0
  186. package/build/treb-charts/src/chart-types.d.ts +233 -0
  187. package/build/treb-charts/src/chart-types.js +57 -0
  188. package/build/treb-charts/src/chart-types.js.map +1 -0
  189. package/build/treb-charts/src/chart-utils.d.ts +106 -0
  190. package/build/treb-charts/src/chart-utils.js +1060 -0
  191. package/build/treb-charts/src/chart-utils.js.map +1 -0
  192. package/build/treb-charts/src/chart.d.ts +23 -0
  193. package/build/treb-charts/src/chart.js +94 -0
  194. package/build/treb-charts/src/chart.js.map +1 -0
  195. package/build/treb-charts/src/default-chart-renderer.d.ts +16 -0
  196. package/build/treb-charts/src/default-chart-renderer.js +533 -0
  197. package/build/treb-charts/src/default-chart-renderer.js.map +1 -0
  198. package/build/treb-charts/src/index.d.ts +5 -0
  199. package/build/treb-charts/src/index.js +24 -0
  200. package/build/treb-charts/src/index.js.map +1 -0
  201. package/build/treb-charts/src/main.d.ts +1 -0
  202. package/build/treb-charts/src/main.js +34 -0
  203. package/build/treb-charts/src/main.js.map +1 -0
  204. package/build/treb-charts/src/quicksort.d.ts +1 -0
  205. package/build/treb-charts/src/quicksort.js +49 -0
  206. package/build/treb-charts/src/quicksort.js.map +1 -0
  207. package/build/treb-charts/src/rectangle.d.ts +18 -0
  208. package/build/treb-charts/src/rectangle.js +41 -0
  209. package/build/treb-charts/src/rectangle.js.map +1 -0
  210. package/build/treb-charts/src/renderer-type.d.ts +24 -0
  211. package/build/treb-charts/src/renderer-type.js +22 -0
  212. package/build/treb-charts/src/renderer-type.js.map +1 -0
  213. package/build/treb-charts/src/renderer.d.ts +127 -0
  214. package/build/treb-charts/src/renderer.js +1518 -0
  215. package/build/treb-charts/src/renderer.js.map +1 -0
  216. package/build/treb-charts/src/util.d.ts +18 -0
  217. package/build/treb-charts/src/util.js +71 -0
  218. package/build/treb-charts/src/util.js.map +1 -0
  219. package/build/treb-data-model/src/annotation.d.ts +167 -0
  220. package/build/treb-data-model/src/annotation.js +120 -0
  221. package/build/treb-data-model/src/annotation.js.map +1 -0
  222. package/build/treb-data-model/src/conditional_format.d.ts +155 -0
  223. package/build/treb-data-model/src/conditional_format.js +62 -0
  224. package/build/treb-data-model/src/conditional_format.js.map +1 -0
  225. package/build/treb-data-model/src/data-validation.d.ts +28 -0
  226. package/build/treb-data-model/src/data-validation.js +22 -0
  227. package/build/treb-data-model/src/data-validation.js.map +1 -0
  228. package/build/treb-data-model/src/data_model.d.ts +173 -0
  229. package/build/treb-data-model/src/data_model.js +637 -0
  230. package/build/treb-data-model/src/data_model.js.map +1 -0
  231. package/build/treb-data-model/src/index.d.ts +13 -0
  232. package/build/treb-data-model/src/index.js +28 -0
  233. package/build/treb-data-model/src/index.js.map +1 -0
  234. package/build/treb-data-model/src/language-model.d.ts +22 -0
  235. package/build/treb-data-model/src/language-model.js +22 -0
  236. package/build/treb-data-model/src/language-model.js.map +1 -0
  237. package/build/treb-data-model/src/named.d.ts +124 -0
  238. package/build/treb-data-model/src/named.js +372 -0
  239. package/build/treb-data-model/src/named.js.map +1 -0
  240. package/build/treb-data-model/src/serialize_options.d.ts +49 -0
  241. package/build/treb-data-model/src/serialize_options.js +22 -0
  242. package/build/treb-data-model/src/serialize_options.js.map +1 -0
  243. package/build/treb-data-model/src/sheet.d.ts +499 -0
  244. package/build/treb-data-model/src/sheet.js +2904 -0
  245. package/build/treb-data-model/src/sheet.js.map +1 -0
  246. package/build/treb-data-model/src/sheet_collection.d.ts +58 -0
  247. package/build/treb-data-model/src/sheet_collection.js +112 -0
  248. package/build/treb-data-model/src/sheet_collection.js.map +1 -0
  249. package/build/treb-data-model/src/sheet_selection.d.ts +42 -0
  250. package/build/treb-data-model/src/sheet_selection.js +39 -0
  251. package/build/treb-data-model/src/sheet_selection.js.map +1 -0
  252. package/build/treb-data-model/src/sheet_types.d.ts +104 -0
  253. package/build/treb-data-model/src/sheet_types.js +22 -0
  254. package/build/treb-data-model/src/sheet_types.js.map +1 -0
  255. package/build/treb-data-model/src/types.d.ts +59 -0
  256. package/build/treb-data-model/src/types.js +22 -0
  257. package/build/treb-data-model/src/types.js.map +1 -0
  258. package/build/treb-embed/src/custom-element/spreadsheet-constructor.d.ts +75 -0
  259. package/build/treb-embed/src/custom-element/spreadsheet-constructor.js +1144 -0
  260. package/build/treb-embed/src/custom-element/spreadsheet-constructor.js.map +1 -0
  261. package/build/treb-embed/src/custom-element/treb-global.d.ts +36 -0
  262. package/build/treb-embed/src/custom-element/treb-global.js +64 -0
  263. package/build/treb-embed/src/custom-element/treb-global.js.map +1 -0
  264. package/build/treb-embed/src/custom-element/treb-spreadsheet-element.d.ts +1 -0
  265. package/build/treb-embed/src/custom-element/treb-spreadsheet-element.js +61 -0
  266. package/build/treb-embed/src/custom-element/treb-spreadsheet-element.js.map +1 -0
  267. package/build/treb-embed/src/embedded-spreadsheet.d.ts +1358 -0
  268. package/build/treb-embed/src/embedded-spreadsheet.js +5205 -0
  269. package/build/treb-embed/src/embedded-spreadsheet.js.map +1 -0
  270. package/build/treb-embed/src/index.d.ts +12 -0
  271. package/build/treb-embed/src/index.js +34 -0
  272. package/build/treb-embed/src/index.js.map +1 -0
  273. package/build/treb-embed/src/options.d.ts +266 -0
  274. package/build/treb-embed/src/options.js +56 -0
  275. package/build/treb-embed/src/options.js.map +1 -0
  276. package/build/treb-embed/src/plugin.d.ts +9 -0
  277. package/build/treb-embed/src/plugin.js +22 -0
  278. package/build/treb-embed/src/plugin.js.map +1 -0
  279. package/build/treb-embed/src/progress-dialog.d.ts +49 -0
  280. package/build/treb-embed/src/progress-dialog.js +178 -0
  281. package/build/treb-embed/src/progress-dialog.js.map +1 -0
  282. package/build/treb-embed/src/selection-state.d.ts +15 -0
  283. package/build/treb-embed/src/selection-state.js +22 -0
  284. package/build/treb-embed/src/selection-state.js.map +1 -0
  285. package/build/treb-embed/src/spinner.d.ts +8 -0
  286. package/build/treb-embed/src/spinner.js +40 -0
  287. package/build/treb-embed/src/spinner.js.map +1 -0
  288. package/build/treb-embed/src/toolbar-message.d.ts +72 -0
  289. package/build/treb-embed/src/toolbar-message.js +22 -0
  290. package/build/treb-embed/src/toolbar-message.js.map +1 -0
  291. package/build/treb-embed/src/types.d.ts +185 -0
  292. package/build/treb-embed/src/types.js +45 -0
  293. package/build/treb-embed/src/types.js.map +1 -0
  294. package/build/treb-embed/tsconfig.tsbuildinfo +1 -0
  295. package/build/treb-export/src/address-type.d.ts +34 -0
  296. package/build/treb-export/src/address-type.js +53 -0
  297. package/build/treb-export/src/address-type.js.map +1 -0
  298. package/build/treb-export/src/base-template.d.ts +1 -0
  299. package/build/treb-export/src/base-template.js +22 -0
  300. package/build/treb-export/src/base-template.js.map +1 -0
  301. package/build/treb-export/src/column-width.d.ts +2 -0
  302. package/build/treb-export/src/column-width.js +80 -0
  303. package/build/treb-export/src/column-width.js.map +1 -0
  304. package/build/treb-export/src/drawing/bubble-chart-template.d.ts +514 -0
  305. package/build/treb-export/src/drawing/bubble-chart-template.js +544 -0
  306. package/build/treb-export/src/drawing/bubble-chart-template.js.map +1 -0
  307. package/build/treb-export/src/drawing/chart-template-components2.d.ts +365 -0
  308. package/build/treb-export/src/drawing/chart-template-components2.js +386 -0
  309. package/build/treb-export/src/drawing/chart-template-components2.js.map +1 -0
  310. package/build/treb-export/src/drawing/chart.d.ts +26 -0
  311. package/build/treb-export/src/drawing/chart.js +247 -0
  312. package/build/treb-export/src/drawing/chart.js.map +1 -0
  313. package/build/treb-export/src/drawing/column-chart-template2.d.ts +490 -0
  314. package/build/treb-export/src/drawing/column-chart-template2.js +518 -0
  315. package/build/treb-export/src/drawing/column-chart-template2.js.map +1 -0
  316. package/build/treb-export/src/drawing/donut-chart-template2.d.ts +272 -0
  317. package/build/treb-export/src/drawing/donut-chart-template2.js +293 -0
  318. package/build/treb-export/src/drawing/donut-chart-template2.js.map +1 -0
  319. package/build/treb-export/src/drawing/drawing.d.ts +49 -0
  320. package/build/treb-export/src/drawing/drawing.js +193 -0
  321. package/build/treb-export/src/drawing/drawing.js.map +1 -0
  322. package/build/treb-export/src/drawing/embedded-image.d.ts +12 -0
  323. package/build/treb-export/src/drawing/embedded-image.js +54 -0
  324. package/build/treb-export/src/drawing/embedded-image.js.map +1 -0
  325. package/build/treb-export/src/drawing/scatter-chart-template2.d.ts +520 -0
  326. package/build/treb-export/src/drawing/scatter-chart-template2.js +551 -0
  327. package/build/treb-export/src/drawing/scatter-chart-template2.js.map +1 -0
  328. package/build/treb-export/src/export.d.ts +72 -0
  329. package/build/treb-export/src/export.js +2039 -0
  330. package/build/treb-export/src/export.js.map +1 -0
  331. package/build/treb-export/src/import-export-messages.d.ts +31 -0
  332. package/build/treb-export/src/import-export-messages.js +22 -0
  333. package/build/treb-export/src/import-export-messages.js.map +1 -0
  334. package/build/treb-export/src/import.d.ts +33 -0
  335. package/build/treb-export/src/import.js +1258 -0
  336. package/build/treb-export/src/import.js.map +1 -0
  337. package/build/treb-export/src/index.worker.d.ts +1 -0
  338. package/build/treb-export/src/index.worker.js +93 -0
  339. package/build/treb-export/src/index.worker.js.map +1 -0
  340. package/build/treb-export/src/metadata.d.ts +51 -0
  341. package/build/treb-export/src/metadata.js +153 -0
  342. package/build/treb-export/src/metadata.js.map +1 -0
  343. package/build/treb-export/src/ooxml.d.ts +7 -0
  344. package/build/treb-export/src/ooxml.js +41 -0
  345. package/build/treb-export/src/ooxml.js.map +1 -0
  346. package/build/treb-export/src/relationship.d.ts +8 -0
  347. package/build/treb-export/src/relationship.js +27 -0
  348. package/build/treb-export/src/relationship.js.map +1 -0
  349. package/build/treb-export/src/shared-strings.d.ts +11 -0
  350. package/build/treb-export/src/shared-strings.js +105 -0
  351. package/build/treb-export/src/shared-strings.js.map +1 -0
  352. package/build/treb-export/src/template-2.d.ts +1 -0
  353. package/build/treb-export/src/template-2.js +22 -0
  354. package/build/treb-export/src/template-2.js.map +1 -0
  355. package/build/treb-export/src/unescape_xml.d.ts +1 -0
  356. package/build/treb-export/src/unescape_xml.js +61 -0
  357. package/build/treb-export/src/unescape_xml.js.map +1 -0
  358. package/build/treb-export/src/workbook-sheet.d.ts +75 -0
  359. package/build/treb-export/src/workbook-sheet.js +128 -0
  360. package/build/treb-export/src/workbook-sheet.js.map +1 -0
  361. package/build/treb-export/src/workbook-style.d.ts +110 -0
  362. package/build/treb-export/src/workbook-style.js +1134 -0
  363. package/build/treb-export/src/workbook-style.js.map +1 -0
  364. package/build/treb-export/src/workbook-theme.d.ts +13 -0
  365. package/build/treb-export/src/workbook-theme.js +85 -0
  366. package/build/treb-export/src/workbook-theme.js.map +1 -0
  367. package/build/treb-export/src/workbook.d.ts +123 -0
  368. package/build/treb-export/src/workbook.js +644 -0
  369. package/build/treb-export/src/workbook.js.map +1 -0
  370. package/build/treb-export/src/xml-test.d.ts +9 -0
  371. package/build/treb-export/src/xml-test.js +52 -0
  372. package/build/treb-export/src/xml-test.js.map +1 -0
  373. package/build/treb-export/src/xml-utils.d.ts +76 -0
  374. package/build/treb-export/src/xml-utils.js +223 -0
  375. package/build/treb-export/src/xml-utils.js.map +1 -0
  376. package/build/treb-export/src/zip-wrapper.d.ts +22 -0
  377. package/build/treb-export/src/zip-wrapper.js +93 -0
  378. package/build/treb-export/src/zip-wrapper.js.map +1 -0
  379. package/build/treb-format/src/format.d.ts +130 -0
  380. package/build/treb-format/src/format.js +805 -0
  381. package/build/treb-format/src/format.js.map +1 -0
  382. package/build/treb-format/src/format_cache.d.ts +55 -0
  383. package/build/treb-format/src/format_cache.js +166 -0
  384. package/build/treb-format/src/format_cache.js.map +1 -0
  385. package/build/treb-format/src/format_parser.d.ts +70 -0
  386. package/build/treb-format/src/format_parser.js +618 -0
  387. package/build/treb-format/src/format_parser.js.map +1 -0
  388. package/build/treb-format/src/index.d.ts +4 -0
  389. package/build/treb-format/src/index.js +25 -0
  390. package/build/treb-format/src/index.js.map +1 -0
  391. package/build/treb-format/src/number_format_section.d.ts +58 -0
  392. package/build/treb-format/src/number_format_section.js +78 -0
  393. package/build/treb-format/src/number_format_section.js.map +1 -0
  394. package/build/treb-format/src/value_parser.d.ts +48 -0
  395. package/build/treb-format/src/value_parser.js +244 -0
  396. package/build/treb-format/src/value_parser.js.map +1 -0
  397. package/build/treb-grid/src/editors/autocomplete.d.ts +39 -0
  398. package/build/treb-grid/src/editors/autocomplete.js +316 -0
  399. package/build/treb-grid/src/editors/autocomplete.js.map +1 -0
  400. package/build/treb-grid/src/editors/autocomplete_matcher.d.ts +74 -0
  401. package/build/treb-grid/src/editors/autocomplete_matcher.js +212 -0
  402. package/build/treb-grid/src/editors/autocomplete_matcher.js.map +1 -0
  403. package/build/treb-grid/src/editors/editor.d.ts +214 -0
  404. package/build/treb-grid/src/editors/editor.js +879 -0
  405. package/build/treb-grid/src/editors/editor.js.map +1 -0
  406. package/build/treb-grid/src/editors/external_editor.d.ts +11 -0
  407. package/build/treb-grid/src/editors/external_editor.js +118 -0
  408. package/build/treb-grid/src/editors/external_editor.js.map +1 -0
  409. package/build/treb-grid/src/editors/formula_bar.d.ts +85 -0
  410. package/build/treb-grid/src/editors/formula_bar.js +444 -0
  411. package/build/treb-grid/src/editors/formula_bar.js.map +1 -0
  412. package/build/treb-grid/src/editors/overlay_editor.d.ts +85 -0
  413. package/build/treb-grid/src/editors/overlay_editor.js +353 -0
  414. package/build/treb-grid/src/editors/overlay_editor.js.map +1 -0
  415. package/build/treb-grid/src/index.d.ts +12 -0
  416. package/build/treb-grid/src/index.js +28 -0
  417. package/build/treb-grid/src/index.js.map +1 -0
  418. package/build/treb-grid/src/layout/base_layout.d.ts +346 -0
  419. package/build/treb-grid/src/layout/base_layout.js +2050 -0
  420. package/build/treb-grid/src/layout/base_layout.js.map +1 -0
  421. package/build/treb-grid/src/layout/grid_layout.d.ts +19 -0
  422. package/build/treb-grid/src/layout/grid_layout.js +235 -0
  423. package/build/treb-grid/src/layout/grid_layout.js.map +1 -0
  424. package/build/treb-grid/src/layout/mock-layout.d.ts +10 -0
  425. package/build/treb-grid/src/layout/mock-layout.js +37 -0
  426. package/build/treb-grid/src/layout/mock-layout.js.map +1 -0
  427. package/build/treb-grid/src/render/selection-renderer.d.ts +97 -0
  428. package/build/treb-grid/src/render/selection-renderer.js +315 -0
  429. package/build/treb-grid/src/render/selection-renderer.js.map +1 -0
  430. package/build/treb-grid/src/render/svg_header_overlay.d.ts +20 -0
  431. package/build/treb-grid/src/render/svg_header_overlay.js +76 -0
  432. package/build/treb-grid/src/render/svg_header_overlay.js.map +1 -0
  433. package/build/treb-grid/src/render/svg_selection_block.d.ts +27 -0
  434. package/build/treb-grid/src/render/svg_selection_block.js +106 -0
  435. package/build/treb-grid/src/render/svg_selection_block.js.map +1 -0
  436. package/build/treb-grid/src/render/tile_renderer.d.ts +121 -0
  437. package/build/treb-grid/src/render/tile_renderer.js +1609 -0
  438. package/build/treb-grid/src/render/tile_renderer.js.map +1 -0
  439. package/build/treb-grid/src/types/border_constants.d.ts +9 -0
  440. package/build/treb-grid/src/types/border_constants.js +34 -0
  441. package/build/treb-grid/src/types/border_constants.js.map +1 -0
  442. package/build/treb-grid/src/types/clipboard_data.d.ts +11 -0
  443. package/build/treb-grid/src/types/clipboard_data.js +22 -0
  444. package/build/treb-grid/src/types/clipboard_data.js.map +1 -0
  445. package/build/treb-grid/src/types/clipboard_data2.d.ts +46 -0
  446. package/build/treb-grid/src/types/clipboard_data2.js +22 -0
  447. package/build/treb-grid/src/types/clipboard_data2.js.map +1 -0
  448. package/build/treb-grid/src/types/drag_mask.d.ts +10 -0
  449. package/build/treb-grid/src/types/drag_mask.js +78 -0
  450. package/build/treb-grid/src/types/drag_mask.js.map +1 -0
  451. package/build/treb-grid/src/types/external_editor_config.d.ts +33 -0
  452. package/build/treb-grid/src/types/external_editor_config.js +22 -0
  453. package/build/treb-grid/src/types/external_editor_config.js.map +1 -0
  454. package/build/treb-grid/src/types/grid.d.ts +806 -0
  455. package/build/treb-grid/src/types/grid.js +6410 -0
  456. package/build/treb-grid/src/types/grid.js.map +1 -0
  457. package/build/treb-grid/src/types/grid_base.d.ts +442 -0
  458. package/build/treb-grid/src/types/grid_base.js +3523 -0
  459. package/build/treb-grid/src/types/grid_base.js.map +1 -0
  460. package/build/treb-grid/src/types/grid_command.d.ts +408 -0
  461. package/build/treb-grid/src/types/grid_command.js +75 -0
  462. package/build/treb-grid/src/types/grid_command.js.map +1 -0
  463. package/build/treb-grid/src/types/grid_events.d.ts +93 -0
  464. package/build/treb-grid/src/types/grid_events.js +36 -0
  465. package/build/treb-grid/src/types/grid_events.js.map +1 -0
  466. package/build/treb-grid/src/types/grid_options.d.ts +50 -0
  467. package/build/treb-grid/src/types/grid_options.js +34 -0
  468. package/build/treb-grid/src/types/grid_options.js.map +1 -0
  469. package/build/treb-grid/src/types/scale-control.d.ts +21 -0
  470. package/build/treb-grid/src/types/scale-control.js +148 -0
  471. package/build/treb-grid/src/types/scale-control.js.map +1 -0
  472. package/build/treb-grid/src/types/set_range_options.d.ts +24 -0
  473. package/build/treb-grid/src/types/set_range_options.js +22 -0
  474. package/build/treb-grid/src/types/set_range_options.js.map +1 -0
  475. package/build/treb-grid/src/types/tab_bar.d.ts +84 -0
  476. package/build/treb-grid/src/types/tab_bar.js +426 -0
  477. package/build/treb-grid/src/types/tab_bar.js.map +1 -0
  478. package/build/treb-grid/src/types/tile.d.ts +29 -0
  479. package/build/treb-grid/src/types/tile.js +22 -0
  480. package/build/treb-grid/src/types/tile.js.map +1 -0
  481. package/build/treb-grid/src/types/update_flags.d.ts +48 -0
  482. package/build/treb-grid/src/types/update_flags.js +22 -0
  483. package/build/treb-grid/src/types/update_flags.js.map +1 -0
  484. package/build/treb-grid/src/util/fontmetrics.d.ts +21 -0
  485. package/build/treb-grid/src/util/fontmetrics.js +82 -0
  486. package/build/treb-grid/src/util/fontmetrics.js.map +1 -0
  487. package/build/treb-grid/src/util/ua.d.ts +33 -0
  488. package/build/treb-grid/src/util/ua.js +86 -0
  489. package/build/treb-grid/src/util/ua.js.map +1 -0
  490. package/build/treb-parser/src/csv-parser.d.ts +13 -0
  491. package/build/treb-parser/src/csv-parser.js +107 -0
  492. package/build/treb-parser/src/csv-parser.js.map +1 -0
  493. package/build/treb-parser/src/index.d.ts +4 -0
  494. package/build/treb-parser/src/index.js +25 -0
  495. package/build/treb-parser/src/index.js.map +1 -0
  496. package/build/treb-parser/src/md-parser.d.ts +97 -0
  497. package/build/treb-parser/src/md-parser.js +403 -0
  498. package/build/treb-parser/src/md-parser.js.map +1 -0
  499. package/build/treb-parser/src/parser-types.d.ts +345 -0
  500. package/build/treb-parser/src/parser-types.js +53 -0
  501. package/build/treb-parser/src/parser-types.js.map +1 -0
  502. package/build/treb-parser/src/parser.d.ts +422 -0
  503. package/build/treb-parser/src/parser.js +2418 -0
  504. package/build/treb-parser/src/parser.js.map +1 -0
  505. package/build/treb-utils/src/event_source.d.ts +34 -0
  506. package/build/treb-utils/src/event_source.js +110 -0
  507. package/build/treb-utils/src/event_source.js.map +1 -0
  508. package/build/treb-utils/src/ievent_source.d.ts +9 -0
  509. package/build/treb-utils/src/ievent_source.js +22 -0
  510. package/build/treb-utils/src/ievent_source.js.map +1 -0
  511. package/build/treb-utils/src/index.d.ts +6 -0
  512. package/build/treb-utils/src/index.js +30 -0
  513. package/build/treb-utils/src/index.js.map +1 -0
  514. package/build/treb-utils/src/measurement.d.ts +42 -0
  515. package/build/treb-utils/src/measurement.js +145 -0
  516. package/build/treb-utils/src/measurement.js.map +1 -0
  517. package/build/treb-utils/src/scale.d.ts +16 -0
  518. package/build/treb-utils/src/scale.js +106 -0
  519. package/build/treb-utils/src/scale.js.map +1 -0
  520. package/build/treb-utils/src/serialize_html.d.ts +5 -0
  521. package/build/treb-utils/src/serialize_html.js +128 -0
  522. package/build/treb-utils/src/serialize_html.js.map +1 -0
  523. package/build/treb-utils/src/validate_uri.d.ts +20 -0
  524. package/build/treb-utils/src/validate_uri.js +55 -0
  525. package/build/treb-utils/src/validate_uri.js.map +1 -0
  526. package/dist/{chunk-Z4XFMZ2X.mjs → chunk-E35ONJUS.mjs} +1 -1
  527. package/dist/treb-export-worker.mjs +2 -2
  528. package/dist/treb-spreadsheet.mjs +4 -4
  529. package/dist/treb.d.ts +1 -1
  530. package/esbuild-composite.mjs +5 -1
  531. package/package.json +67 -3
  532. package/treb-embed/src/custom-element/spreadsheet-constructor.ts +7 -3
  533. package/treb-embed/src/embedded-spreadsheet.ts +1 -1
  534. package/treb-grid/src/types/grid_options.ts +1 -1
  535. package/tsproject.json +1 -2
  536. package/dist/chunk-43DLP2OX.mjs +0 -11
  537. package/dist/chunk-4CKS56PE.mjs +0 -11
  538. package/dist/chunk-75PARUQE.mjs +0 -11
  539. package/dist/chunk-7QD63AZS.mjs +0 -24601
  540. package/dist/chunk-A55ARVRD.mjs +0 -11
  541. package/dist/chunk-DESAKYW4.mjs +0 -11
  542. package/dist/chunk-EQ2R5W6P.mjs +0 -24565
  543. package/dist/chunk-IYJU2J6D.mjs +0 -24601
  544. package/dist/chunk-KSJFPGXT.mjs +0 -11
  545. package/dist/chunk-MQK4DNXI.mjs +0 -11
  546. package/dist/chunk-ORQFKLXM.mjs +0 -24601
  547. package/dist/chunk-SFDNNDHY.mjs +0 -11
  548. package/dist/chunk-T47DX5MI.mjs +0 -11
  549. package/dist/chunk-T6ILBVEX.mjs +0 -11
  550. package/dist/chunk-TPRCDYYG.mjs +0 -11
  551. package/dist/chunk-YAHNOOHO.mjs +0 -11
  552. package/dist/chunk-YLCFKX2G.mjs +0 -24601
@@ -0,0 +1,1144 @@
1
+ /*
2
+ * This file is part of TREB.
3
+ *
4
+ * TREB is free software: you can redistribute it and/or modify it under the
5
+ * terms of the GNU General Public License as published by the Free Software
6
+ * Foundation, either version 3 of the License, or (at your option) any
7
+ * later version.
8
+ *
9
+ * TREB is distributed in the hope that it will be useful, but WITHOUT ANY
10
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
11
+ * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
12
+ * details.
13
+ *
14
+ * You should have received a copy of the GNU General Public License along
15
+ * with TREB. If not, see <https://www.gnu.org/licenses/>.
16
+ *
17
+ * Copyright 2022-2026 trebco, llc.
18
+ * info@treb.app
19
+ *
20
+ */
21
+ import { EmbeddedSpreadsheet } from '../embedded-spreadsheet';
22
+ import css from 'treb-embed/style/treb-spreadsheet-element.scss';
23
+ import html from 'treb-embed/markup/layout.html';
24
+ import toolbar_html from 'treb-embed/markup/toolbar.html';
25
+ // import css from '../../style/treb-spreadsheet-element.scss';
26
+ // import html from '../../markup/layout.html';
27
+ // import toolbar_html from '../../markup/toolbar.html';
28
+ import { NumberFormatCache } from 'treb-format';
29
+ import { ColorFunctions, IsThemeColor } from 'treb-base-types';
30
+ import { Measurement } from 'treb-utils';
31
+ import { DOMContext } from 'treb-base-types';
32
+ import { font_stack_labels } from 'treb-base-types/src/font-stack';
33
+ /** with a view towards i18n */
34
+ const default_titles = {
35
+ close_dialog: 'Close dialog',
36
+ insert_function: 'Insert function...',
37
+ delete_sheet: 'Delete current sheet',
38
+ add_sheet: 'Add sheet',
39
+ document_modified: 'This document has been modified from the original version.',
40
+ recalculate: 'Recalculate',
41
+ toggle_toolbar: 'Toggle toolbar',
42
+ export: 'Export as XLSX',
43
+ revert: 'Revert to original version',
44
+ about: `What's this?`,
45
+ toggle_sidebar: 'Toggle sidebar',
46
+ };
47
+ /** @internal */
48
+ export class SpreadsheetConstructor {
49
+ /** container, if any */
50
+ root;
51
+ /** spreadsheet instance */
52
+ sheet;
53
+ /** current border color. will be applied to new borders. */
54
+ border_color;
55
+ /** color bar elements, since we update them frequently */
56
+ color_bar_elements = {};
57
+ /** some menu buttons change icons from time to time */
58
+ replace_targets = {};
59
+ /** root layout element */
60
+ layout_element;
61
+ /** views container */
62
+ views;
63
+ /**
64
+ * handle to the revert button, so we can adjust it. we can use
65
+ * container classes for the most part but we are updating the title.
66
+ * (FIXME: double-up the button, no reference required)
67
+ */
68
+ revert_button;
69
+ revert_state = false;
70
+ /** cached controls */
71
+ toolbar_controls = {};
72
+ /** swatch lists in color chooser */
73
+ swatch_lists = {};
74
+ DOM;
75
+ //
76
+ constructor(root) {
77
+ if (typeof root === 'string') {
78
+ root = document.querySelector(root);
79
+ }
80
+ this.DOM = DOMContext.GetInstance(root?.ownerDocument);
81
+ // there's a possibility this could be running in a node environment.
82
+ // in that case (wihtout a shim) HTMLElement will not exist, so we can't
83
+ // check type.
84
+ // but in that case what would root be? (...)
85
+ if (this.DOM.view && root instanceof this.DOM.view.HTMLElement) {
86
+ this.root = root;
87
+ const style_node = this.DOM.doc?.head.querySelector('style[treb-stylesheet]');
88
+ if (!style_node) {
89
+ this.DOM.doc?.head.prepend(this.DOM.Create('style', undefined, undefined, { text: css, attrs: { 'treb-stylesheet': '' } }));
90
+ }
91
+ }
92
+ }
93
+ /**
94
+ * coerce an attribute value into a more useful type. for attributes,
95
+ * having no value implies "true". false should be explicitly set as
96
+ * "false"; we don't, atm, support falsy values like '0' (that would be
97
+ * coerced to a number).
98
+ */
99
+ CoerceAttributeValue(value) {
100
+ if (value === null || value.toString().toLowerCase() === 'true' || value === '') {
101
+ return true;
102
+ }
103
+ else if (value.toLowerCase() === 'false') {
104
+ return false;
105
+ }
106
+ else {
107
+ const test = Number(value);
108
+ if (!isNaN(test)) {
109
+ return test;
110
+ }
111
+ }
112
+ // default to string, if it was null default to empty string (no nulls)
113
+ return value || '';
114
+ }
115
+ /**
116
+ * get options from node attributes. we're still working on final
117
+ * semantics but at the moment we'll translate hyphen-separated-options
118
+ * to our standard snake_case_options.
119
+ *
120
+ * we also support the old-style data-options
121
+ *
122
+ * @returns
123
+ */
124
+ ParseOptionAttributes() {
125
+ const attribute_options = {};
126
+ if (this.root) {
127
+ const names = this.root.getAttributeNames();
128
+ for (const name of names) {
129
+ switch (name) {
130
+ // skip
131
+ case 'class':
132
+ case 'style':
133
+ case 'id':
134
+ continue;
135
+ // old-style options (in two flavors). old-style options are
136
+ // comma-delimited an in the form `key=value`, or just `key`
137
+ // for boolean true.
138
+ case 'data-options':
139
+ case 'options':
140
+ {
141
+ // in this case use the original name, which should
142
+ // be in snake_case (for backcompat)
143
+ const value = this.root.getAttribute(name) || '';
144
+ const elements = value.split(',');
145
+ // console.info(elements);
146
+ for (const element of elements) {
147
+ const parts = element.split(/=/);
148
+ if (parts.length === 1) {
149
+ attribute_options[parts[0]] = true;
150
+ }
151
+ else {
152
+ attribute_options[parts[0]] = this.CoerceAttributeValue(parts[1]);
153
+ }
154
+ }
155
+ }
156
+ continue;
157
+ // old style (not handling though)
158
+ case 'data-treb':
159
+ continue;
160
+ // has special handling as an attribute
161
+ case 'inline-document':
162
+ continue;
163
+ // special case
164
+ case 'src':
165
+ attribute_options.document = this.root.getAttribute('src') || undefined;
166
+ continue;
167
+ }
168
+ // attrtibute options are in kebab-case while our internal
169
+ // options are still in snake_case.
170
+ attribute_options[name.replace(/-/g, '_')] = this.CoerceAttributeValue(this.root.getAttribute(name));
171
+ }
172
+ }
173
+ return {
174
+ ...attribute_options
175
+ };
176
+ }
177
+ /**
178
+ * attach content to element. for custom elements, this is called via
179
+ * the connectedCallback call. for elements created with the API, we
180
+ * call it immediately.
181
+ */
182
+ AttachElement(options = {}) {
183
+ options = {
184
+ ...this.ParseOptionAttributes(),
185
+ ...options,
186
+ };
187
+ if (this.root) {
188
+ // set a default size if the node does not have width or height.
189
+ // we do this with a class, so it's easier to override if desired.
190
+ // could we use vars? (...)
191
+ if (!options.headless) {
192
+ const rect = this.root.getBoundingClientRect();
193
+ if (!rect.width || !rect.height) {
194
+ this.root.classList.add('treb-default-size');
195
+ }
196
+ }
197
+ // inline-document means look in the tag contents for a script
198
+ // element, and use that. the script must have type "application/json",
199
+ // and if it has a name, the name must match the value of the
200
+ // inline-document attribute.
201
+ //
202
+ // so either
203
+ //
204
+ // <treb-spreadsheet inline-document>
205
+ // <script type="application/json">{ ... }</script>
206
+ // </treb-spreadsheet>
207
+ //
208
+ // or
209
+ //
210
+ // <treb-spreadsheet inline-document="xyz">
211
+ // <script type="application/json" name="xyz">{ ... }</script>
212
+ // </treb-spreadsheet>
213
+ if (this.root.hasAttribute('inline-document')) {
214
+ const inline_name = this.root.getAttribute('inline-document') || '';
215
+ for (const element of Array.from(this.root.children)) {
216
+ if (this.DOM.view && element instanceof this.DOM.view.HTMLScriptElement) {
217
+ if (element.type === 'application/json') {
218
+ const name = element.getAttribute('name') || '';
219
+ // add special case for aggressive clients/wrappers
220
+ if (name === inline_name || !name && inline_name === 'true') {
221
+ const content = element.textContent;
222
+ if (content) {
223
+ try {
224
+ options.inline_document = JSON.parse(content);
225
+ }
226
+ catch (err) {
227
+ console.error(err);
228
+ }
229
+ }
230
+ break;
231
+ }
232
+ }
233
+ }
234
+ }
235
+ if (!options.inline_document) {
236
+ console.warn('inline document failed');
237
+ }
238
+ }
239
+ this.root.innerHTML = html;
240
+ options.container = this.root.querySelector('.treb-layout-spreadsheet');
241
+ }
242
+ if (!process.env.XLSX_SUPPORT) {
243
+ options.export = false; // remove export button from sidebar
244
+ }
245
+ // set a local variable so we don't have to keep testing the member
246
+ this.sheet = new EmbeddedSpreadsheet(options);
247
+ if (this.root) {
248
+ this.CreateLayout(this.sheet, this.root);
249
+ }
250
+ }
251
+ CreateLayout(sheet, root) {
252
+ // call our internal resize method when the node is resized
253
+ // (primary instance will handle views)
254
+ // why are we doing this here? ... because this is layout? dunno
255
+ const resizeObserver = new ResizeObserver(() => sheet.Resize());
256
+ resizeObserver.observe(root);
257
+ // const resizeObserver = new ResizeObserver(() => sheet.Resize());
258
+ // resizeObserver.observe(root);
259
+ // handle sidebar collapse
260
+ this.layout_element = root.querySelector('.treb-main');
261
+ const button = root.querySelector('.treb-toggle-sidebar-button');
262
+ if (button && this.layout_element) {
263
+ const element = this.layout_element;
264
+ button.addEventListener('click', () => {
265
+ // attribute is set if it has a value and that value is either
266
+ // empty or "true"; we don't accept any other values, because
267
+ // that just makes extra work.
268
+ const value = element.getAttribute('collapsed');
269
+ const state = (typeof value === 'string' && (value === '' || value === 'true'));
270
+ // toggle
271
+ if (state) {
272
+ element.removeAttribute('collapsed');
273
+ }
274
+ else {
275
+ element.setAttribute('collapsed', '');
276
+ }
277
+ });
278
+ }
279
+ // --- set initial state before enabling transitions -----------------------
280
+ if (sheet.options.toolbar === 'show' || sheet.options.toolbar === 'show-narrow') {
281
+ this.layout_element?.setAttribute('toolbar', '');
282
+ }
283
+ if (sheet.options.collapsed) {
284
+ this.layout_element?.setAttribute('collapsed', '');
285
+ }
286
+ // --- revert indicator ----------------------------------------------------
287
+ const revert_indicator = root.querySelector('[data-command=revert-indicator]');
288
+ if (this.DOM.view && revert_indicator instanceof this.DOM.view.HTMLElement) {
289
+ if (sheet.options.revert_indicator) {
290
+ revert_indicator.addEventListener('click', () => {
291
+ sheet.HandleToolbarMessage({
292
+ command: 'revert-indicator',
293
+ });
294
+ });
295
+ }
296
+ else {
297
+ revert_indicator.style.display = 'none';
298
+ }
299
+ }
300
+ // --- toolbar/sidebar -----------------------------------------------------
301
+ const sidebar = root.querySelector('.treb-layout-sidebar');
302
+ sidebar?.addEventListener('click', event => {
303
+ const target = event.target;
304
+ if (target.dataset.command) {
305
+ switch (target.dataset.command) {
306
+ case 'toggle-toolbar':
307
+ this.ToggleToolbar();
308
+ break;
309
+ default:
310
+ sheet.HandleToolbarMessage({
311
+ command: target.dataset.command,
312
+ });
313
+ break;
314
+ }
315
+ }
316
+ });
317
+ if (sheet.options.toolbar) {
318
+ this.AttachToolbar(sheet, root);
319
+ }
320
+ // --- hide/remove ---------------------------------------------------------
321
+ // compare conditional items against options. not sure which way we're
322
+ // ultimately going to land with the option names. for the time being
323
+ // I'm going to do this the verbose way.
324
+ const conditional_map = {
325
+ // 'file-menu': !!sheet.options.file_menu,
326
+ 'table-button': !!sheet.options.table_button,
327
+ // 'chart-menu': !!sheet.options.chart_menu,
328
+ // 'font-scale': !!sheet.options.font_scale,
329
+ 'revert': !!sheet.options.revert_button,
330
+ 'toolbar': !!sheet.options.toolbar,
331
+ 'export': !!sheet.options.export,
332
+ 'insert-function': !!sheet.options.insert_function_button,
333
+ // the following won't work as expected in split, because this
334
+ // code won't be run when the new view is created -- do something
335
+ // else
336
+ // resize should actually work because we're hiding new view
337
+ // resize handles via positioning
338
+ 'resize': !!sheet.options.resizable,
339
+ // add-tab and delete-tab will still work for the menu
340
+ 'add-tab': !!sheet.options.add_tab,
341
+ 'delete-tab': (!!sheet.options.delete_tab || !!sheet.options.add_tab),
342
+ // we actually don't want to remove stats if it's not in use, because
343
+ // we need it for layout
344
+ // 'stats': !!sheet.options.stats,
345
+ // scale control is not (yet) declarative, so this isn't effective anyway
346
+ // 'scale-control': !!sheet.options.scale_control,
347
+ };
348
+ for (const [key, value] of Object.entries(conditional_map)) {
349
+ if (!value) {
350
+ const elements = this.layout_element.querySelectorAll(`[data-conditional=${key}]`);
351
+ for (const element of Array.from(elements)) {
352
+ element.style.display = 'none';
353
+ }
354
+ }
355
+ }
356
+ if (sheet.options.revert_button) {
357
+ this.revert_button = this.layout_element.querySelector('[data-command=revert]') || undefined;
358
+ }
359
+ // --- resize --------------------------------------------------------------
360
+ if (sheet.options.resizable) {
361
+ const size = { width: 0, height: 0 };
362
+ const position = { x: 0, y: 0 };
363
+ const delta = { x: 0, y: 0 };
364
+ // const resize_container = root.querySelector('.treb-layout-resize-container');
365
+ this.views = root.querySelector('.treb-views') || undefined;
366
+ let mask;
367
+ let resizer;
368
+ const resize_handle = root.querySelector('.treb-layout-resize-handle');
369
+ // mouse up handler added to mask (when created)
370
+ const mouseup = () => finish();
371
+ // mouse move handler added to mask (when created)
372
+ const mousemove = ((event) => {
373
+ if (event.buttons === 0) {
374
+ finish();
375
+ }
376
+ else {
377
+ delta.x = event.screenX - position.x;
378
+ delta.y = event.screenY - position.y;
379
+ if (resizer) {
380
+ resizer.style.width = (size.width + delta.x) + 'px';
381
+ resizer.style.height = (size.height + delta.y) + 'px';
382
+ }
383
+ }
384
+ });
385
+ // clean up mask and layout rectangle
386
+ const finish = () => {
387
+ // resize_handle.classList.remove('retain-opacity'); // we're not using this anymore
388
+ if (delta.x || delta.y) {
389
+ const rect = root.getBoundingClientRect();
390
+ if (!sheet.options.constrain_width) {
391
+ root.style.width = (rect.width + delta.x) + 'px';
392
+ }
393
+ root.style.height = (rect.height + delta.y) + 'px';
394
+ }
395
+ if (mask) {
396
+ mask.removeEventListener('mouseup', mouseup);
397
+ mask.removeEventListener('mousemove', mousemove);
398
+ mask.parentElement?.removeChild(mask);
399
+ mask = undefined;
400
+ }
401
+ resizer?.parentElement?.removeChild(resizer);
402
+ resizer = undefined;
403
+ };
404
+ resize_handle.addEventListener('mousedown', (event) => {
405
+ event.stopPropagation();
406
+ event.preventDefault();
407
+ const resize_parent = root.querySelector('.treb-main'); // was document.body
408
+ resizer = this.DOM.Div('treb-resize-rect', resize_parent);
409
+ mask = this.DOM.Div('treb-resize-mask', resize_parent, {
410
+ attrs: {
411
+ style: 'cursor: nw-resize;'
412
+ },
413
+ events: { mouseup, mousemove },
414
+ });
415
+ // mask.addEventListener('mouseup', mouse_up);
416
+ // mask.addEventListener('mousemove', mouse_move);
417
+ // resize_handle.classList.add('retain-opacity'); // we're not using this anymore
418
+ position.x = event.screenX;
419
+ position.y = event.screenY;
420
+ delta.x = 0;
421
+ delta.y = 0;
422
+ const layouts = this.views?.querySelectorAll('.treb-spreadsheet-body');
423
+ const rects = Array.from(layouts || []).map(element => element.getBoundingClientRect());
424
+ if (rects.length) {
425
+ const composite = JSON.parse(JSON.stringify(rects.shift()));
426
+ for (const rect of rects) {
427
+ composite.top = Math.min(rect.top, composite.top);
428
+ composite.left = Math.min(rect.left, composite.left);
429
+ composite.right = Math.max(rect.right, composite.right);
430
+ composite.bottom = Math.max(rect.bottom, composite.bottom);
431
+ }
432
+ const width = composite.right - composite.left;
433
+ const height = composite.bottom - composite.top;
434
+ resizer.style.top = (composite.top) + 'px';
435
+ resizer.style.left = (composite.left) + 'px';
436
+ resizer.style.width = (width) + 'px';
437
+ resizer.style.height = (height) + 'px';
438
+ size.width = width;
439
+ size.height = height;
440
+ }
441
+ });
442
+ }
443
+ // --- titles --------------------------------------------------------------
444
+ const elements = Array.from(this.layout_element.querySelectorAll('[data-title]'));
445
+ for (const element of elements) {
446
+ if (element instanceof HTMLElement) {
447
+ // temp workaround
448
+ if (element.dataset.activeTitle) {
449
+ continue;
450
+ }
451
+ if (element.dataset.title && default_titles[element.dataset.title]) {
452
+ element.title = default_titles[element.dataset.title];
453
+ }
454
+ }
455
+ }
456
+ // --- animated ------------------------------------------------------------
457
+ // requestAnimationFrame(() => {
458
+ setTimeout(() => this.layout_element?.setAttribute('animate', ''), 250);
459
+ }
460
+ ToggleToolbar() {
461
+ if (this.layout_element) {
462
+ const value = this.layout_element.getAttribute('toolbar');
463
+ const state = (typeof value === 'string' && (value === '' || value === 'true'));
464
+ if (state) {
465
+ this.layout_element.removeAttribute('toolbar');
466
+ }
467
+ else {
468
+ this.layout_element.setAttribute('toolbar', '');
469
+ }
470
+ }
471
+ }
472
+ UpdateSelectionStyle(sheet, toolbar, comment_box) {
473
+ const state = sheet.selection_state;
474
+ // unset all
475
+ comment_box.value = '';
476
+ for (const value of Object.values(this.toolbar_controls)) {
477
+ if (value) {
478
+ // value.classList.remove('treb-active');
479
+ value.removeAttribute('active');
480
+ if (value.dataset.inactiveTitle) {
481
+ value.title = value.dataset.inactiveTitle;
482
+ }
483
+ }
484
+ }
485
+ const Activate = (element) => {
486
+ if (element) {
487
+ // element.classList.add('treb-active');
488
+ element.setAttribute('active', '');
489
+ if (element.dataset.activeTitle) {
490
+ element.title = element.dataset.activeTitle;
491
+ }
492
+ }
493
+ };
494
+ if (state.comment) {
495
+ Activate(this.toolbar_controls.comment);
496
+ comment_box.value = state.comment;
497
+ }
498
+ if (state.style?.locked) {
499
+ Activate(this.toolbar_controls.locked);
500
+ }
501
+ if (state.frozen) {
502
+ Activate(this.toolbar_controls.freeze);
503
+ }
504
+ if (state.style?.wrap) {
505
+ Activate(this.toolbar_controls.wrap);
506
+ }
507
+ if (this.toolbar_controls.table) {
508
+ if (state.table) {
509
+ Activate(this.toolbar_controls.table);
510
+ this.toolbar_controls.table.dataset.command = 'remove-table';
511
+ }
512
+ else {
513
+ this.toolbar_controls.table.dataset.command = 'insert-table';
514
+ }
515
+ }
516
+ if (this.toolbar_controls.merge) {
517
+ if (state.merge) {
518
+ Activate(this.toolbar_controls.merge);
519
+ this.toolbar_controls.merge.dataset.command = 'unmerge-cells';
520
+ }
521
+ else {
522
+ this.toolbar_controls.merge.dataset.command = 'merge-cells';
523
+ }
524
+ }
525
+ if (this.toolbar_controls.stack) {
526
+ if (state.style?.font_face) {
527
+ if (state.style.font_face.startsWith('stack:')) {
528
+ const stack_name = state.style.font_face.substring(6);
529
+ this.toolbar_controls.stack.textContent = font_stack_labels[stack_name] || '';
530
+ this.toolbar_controls.stack.dataset.fontStack = stack_name;
531
+ }
532
+ else {
533
+ this.toolbar_controls.stack.textContent = '';
534
+ this.toolbar_controls.stack.dataset.fontStack = '';
535
+ }
536
+ }
537
+ else { // } if (!state.empty) {
538
+ this.toolbar_controls.stack.textContent = font_stack_labels.default || '';
539
+ this.toolbar_controls.stack.dataset.fontStack = 'default';
540
+ }
541
+ }
542
+ const format = this.toolbar_controls.format;
543
+ if (format) {
544
+ if (state.style?.number_format) {
545
+ format.value = NumberFormatCache.SymbolicName(state.style.number_format) || state.style.number_format;
546
+ }
547
+ else {
548
+ format.value = 'General';
549
+ }
550
+ }
551
+ const scale = this.toolbar_controls.scale;
552
+ if (scale) {
553
+ scale.value = sheet.FormatNumber(state.relative_font_size || 1, '0.00');
554
+ }
555
+ switch (state.style?.horizontal_align) {
556
+ case 'left':
557
+ Activate(this.toolbar_controls.left);
558
+ break;
559
+ case 'center':
560
+ Activate(this.toolbar_controls.center);
561
+ break;
562
+ case 'right':
563
+ Activate(this.toolbar_controls.right);
564
+ break;
565
+ }
566
+ switch (state.style?.vertical_align) {
567
+ case 'top':
568
+ Activate(this.toolbar_controls.top);
569
+ break;
570
+ case 'middle':
571
+ Activate(this.toolbar_controls.middle);
572
+ break;
573
+ case 'bottom':
574
+ Activate(this.toolbar_controls.bottom);
575
+ break;
576
+ }
577
+ }
578
+ UpdateDocumentStyles(sheet, format_menu) {
579
+ // --- colors -------------------------------------------------------------
580
+ {
581
+ let fragment = this.DOM.Fragment();
582
+ const length = sheet.document_styles.theme_colors.length;
583
+ const themes = ['Background', 'Text', 'Background', 'Text', 'Accent'];
584
+ if (length) {
585
+ const depth = sheet.document_styles.theme_colors[0].length;
586
+ for (let i = 0; i < depth; i++) {
587
+ for (let j = 0; j < length; j++) {
588
+ const entry = sheet.document_styles.theme_colors[j][i];
589
+ const style = `background: ${entry.resolved};`;
590
+ let title = themes[j] || themes[4];
591
+ if (IsThemeColor(entry.color) && entry.color.tint) {
592
+ title += ` (${(entry.color.tint > 0 ? '+' : '') + (entry.color.tint) * 100}%)`;
593
+ }
594
+ else {
595
+ // set theme default colors
596
+ if (j === 0) {
597
+ this.color_bar_elements.fill?.style.setProperty('--treb-default-color', entry.resolved);
598
+ }
599
+ else if (j === 1) {
600
+ this.color_bar_elements.text?.style.setProperty('--treb-default-color', entry.resolved);
601
+ this.color_bar_elements.border?.style.setProperty('--treb-default-color', entry.resolved);
602
+ }
603
+ }
604
+ this.DOM.Create('button', undefined, fragment, {
605
+ attrs: { style, title },
606
+ data: { command: 'set-color', color: JSON.stringify(entry.color) },
607
+ });
608
+ }
609
+ }
610
+ }
611
+ this.swatch_lists.theme?.replaceChildren(fragment);
612
+ fragment = this.DOM.Fragment();
613
+ /*
614
+ this.DOM.Create('button', 'treb-default-color', fragment, {
615
+ attrs: { title: 'Default color' },
616
+ data: { command: 'set-color', color: JSON.stringify({}) },
617
+ });
618
+ */
619
+ const colors = ['Black', 'White', 'Gray', 'Red', 'Orange', 'Yellow', 'Green', 'Blue', 'Indigo', 'Violet'];
620
+ const lc = colors.map(color => color.toLowerCase());
621
+ const additional_colors = sheet.document_styles.colors.filter(test => {
622
+ return !lc.includes(test.toLowerCase());
623
+ });
624
+ for (const text of [...colors, ...additional_colors]) {
625
+ const style = `background: ${text.toLowerCase()};`;
626
+ this.DOM.Create('button', undefined, fragment, {
627
+ attrs: { style, title: text, },
628
+ data: { command: 'set-color', color: JSON.stringify({ text: text.toLowerCase() }) },
629
+ });
630
+ // Element('button', fragment, { style, title: text, data: { command: 'set-color', color: JSON.stringify({text: text.toLowerCase()})}});
631
+ }
632
+ this.swatch_lists.other?.replaceChildren(fragment);
633
+ }
634
+ // --- number formats -----------------------------------------------------
635
+ const number_formats = [
636
+ 'General', 'Number', 'Integer', 'Percent', 'Fraction', 'Accounting', 'Currency', 'Scientific',
637
+ ];
638
+ const date_formats = [
639
+ 'Timestamp', 'Long Date', 'Short Date',
640
+ ];
641
+ for (const format of sheet.document_styles.number_formats) {
642
+ if (NumberFormatCache.SymbolicName(NumberFormatCache.Translate(format))) {
643
+ continue;
644
+ }
645
+ const instance = NumberFormatCache.Get(format);
646
+ if (instance.date_format) {
647
+ date_formats.push(format);
648
+ }
649
+ else {
650
+ number_formats.push(format);
651
+ }
652
+ }
653
+ const Button = (format) => this.DOM.Create('button', undefined, undefined, {
654
+ text: format,
655
+ data: { format, command: 'number-format' },
656
+ });
657
+ const fragment = this.DOM.Fragment();
658
+ fragment.append(...number_formats.map(format => Button(format)));
659
+ fragment.append(this.DOM.Div(undefined, undefined, { attrs: { separator: '' } }));
660
+ fragment.append(...date_formats.map(format => Button(format)));
661
+ format_menu.textContent = '';
662
+ format_menu.append(fragment);
663
+ }
664
+ /**
665
+ * setting explicit state on the revert button (if enabled).
666
+ *
667
+ * @param sheet
668
+ */
669
+ UpdateRevertState(sheet) {
670
+ const state = sheet.can_revert;
671
+ if (this.revert_state === state) {
672
+ return; // nothing to do
673
+ }
674
+ this.revert_state = state;
675
+ if (this.revert_button || sheet.options.revert_indicator) {
676
+ if (this.revert_state) {
677
+ this.views?.classList.add('treb-can-revert');
678
+ }
679
+ else {
680
+ this.views?.classList.remove('treb-can-revert');
681
+ }
682
+ if (this.revert_button) {
683
+ this.revert_button.dataset.canRevert = state ? 'true' : 'false'; // FIXME: remove
684
+ // FIXME: container classes, double up button
685
+ if (state) {
686
+ this.revert_button.classList.remove('sidebar-disabled');
687
+ this.revert_button.title = 'Revert to original version'; // FIXME: strings
688
+ }
689
+ else {
690
+ this.revert_button.classList.add('sidebar-disabled');
691
+ this.revert_button.title = 'This is the original version of the document'; // FIXME: strings
692
+ }
693
+ }
694
+ }
695
+ }
696
+ /**
697
+ * replace a given template with its contents.
698
+ */
699
+ ReplaceTemplate(root, selector, remove = true) {
700
+ const template = root.querySelector(selector);
701
+ if (template && template.parentElement) {
702
+ // console.info(template, template.parentElement);
703
+ for (const child of Array.from(template.content.children)) {
704
+ template.parentElement.insertBefore(child, template);
705
+ }
706
+ if (remove) {
707
+ template.parentElement.removeChild(template);
708
+ }
709
+ }
710
+ else {
711
+ console.warn('template not found', selector);
712
+ }
713
+ }
714
+ AttachToolbar(sheet, root) {
715
+ // --- layout --------------------------------------------------------------
716
+ const scroller = root.querySelector('.treb-layout-header');
717
+ const toolbar = root.querySelector('.treb-toolbar');
718
+ toolbar.innerHTML = toolbar_html;
719
+ // adjust toolbar based on options
720
+ const remove = [];
721
+ // wide or narrow menu
722
+ if (sheet.options.toolbar === 'narrow' || sheet.options.toolbar === 'show-narrow') {
723
+ remove.push(...Array.from(toolbar.querySelectorAll('[wide]')));
724
+ }
725
+ else {
726
+ remove.push(...Array.from(toolbar.querySelectorAll('[narrow]')));
727
+ }
728
+ // optional toolbar items
729
+ if (!sheet.options.file_menu) {
730
+ remove.push(toolbar.querySelector('[file-menu]'));
731
+ }
732
+ if (!sheet.options.indent_buttons) {
733
+ remove.push(toolbar.querySelector('[indent-group]'));
734
+ }
735
+ if (!sheet.options.font_scale) {
736
+ remove.push(toolbar.querySelector('[font-scale]'));
737
+ }
738
+ if (!sheet.options.font_stack) {
739
+ remove.push(toolbar.querySelector('[font-stack]'));
740
+ }
741
+ else {
742
+ const buttons = toolbar.querySelectorAll(`[font-stack] button[data-font-stack]`);
743
+ for (const button of buttons) {
744
+ if (button.dataset.fontStack) {
745
+ const label = font_stack_labels[button.dataset.fontStack];
746
+ button.textContent = label || '';
747
+ }
748
+ }
749
+ }
750
+ if (!sheet.options.chart_menu) {
751
+ remove.push(toolbar.querySelector('[chart-menu]'));
752
+ }
753
+ if (!sheet.options.freeze_button) {
754
+ remove.push(toolbar.querySelector('[freeze-button]'));
755
+ }
756
+ if (!sheet.options.table_button) {
757
+ remove.push(toolbar.querySelector('[table-button]'));
758
+ }
759
+ if (!sheet.options.add_tab && !sheet.options.delete_tab) {
760
+ remove.push(...Array.from(toolbar.querySelectorAll('[add-remove-sheet]')));
761
+ }
762
+ if (!sheet.options.toolbar_recalculate_button) {
763
+ remove.push(toolbar.querySelector('[recalculate-button]'));
764
+ }
765
+ if (!process.env.XLSX_SUPPORT) {
766
+ remove.push(...Array.from(toolbar.querySelectorAll('[xlsx-support]')));
767
+ }
768
+ for (const element of remove) {
769
+ if (element) {
770
+ element.parentElement?.removeChild(element);
771
+ }
772
+ }
773
+ const color_chooser = toolbar.querySelector('.treb-color-chooser');
774
+ const comment_box = toolbar.querySelector('.treb-comment-box textarea');
775
+ // --- controls ------------------------------------------------------------
776
+ for (const [key, value] of Object.entries({
777
+ // for align/justify make sure we are collecting the wide
778
+ // versions. narrow versions don't highlight.
779
+ 'top': '[wide] [data-command=align-top]',
780
+ 'middle': '[wide] [data-command=align-middle]',
781
+ 'bottom': '[wide] [data-command=align-bottom]',
782
+ 'left': '[wide] [data-command=justify-left]',
783
+ 'right': '[wide] [data-command=justify-right]',
784
+ 'center': '[wide] [data-command=justify-center]',
785
+ 'wrap': '[data-command=wrap-text]',
786
+ 'merge': '[data-id=merge]',
787
+ 'comment': '[data-icon=comment]',
788
+ 'locked': '[data-command=lock-cells]',
789
+ 'freeze': '[data-command=freeze-panes]',
790
+ 'table': '[data-icon=table]',
791
+ 'format': 'input.treb-number-format',
792
+ 'scale': 'input.treb-font-scale',
793
+ 'stack': 'button.treb-font-stack',
794
+ })) {
795
+ const element = toolbar.querySelector(value);
796
+ if (element) {
797
+ this.toolbar_controls[key] = element;
798
+ }
799
+ else {
800
+ // console.warn('missing toolbar element', value);
801
+ }
802
+ }
803
+ const swatch_lists = color_chooser.querySelectorAll('.treb-swatches');
804
+ this.swatch_lists = {
805
+ theme: swatch_lists[0],
806
+ other: swatch_lists[1],
807
+ };
808
+ let button = root.querySelector('[data-command=increase-precision');
809
+ if (button) {
810
+ button.textContent = this.sheet?.FormatNumber(0, '0.00') || '';
811
+ }
812
+ button = root.querySelector('[data-command=decrease-precision');
813
+ if (button) {
814
+ button.textContent = this.sheet?.FormatNumber(0, '0.0') || '';
815
+ }
816
+ button = toolbar.querySelector('[data-command=update-comment]');
817
+ comment_box.addEventListener('keydown', event => {
818
+ if (event.key === 'Enter' && (event.shiftKey || event.ctrlKey)) {
819
+ button.click();
820
+ }
821
+ });
822
+ // why are we not just getting all? (...)
823
+ for (const entry of ['border', 'annotation', 'align', 'justify']) {
824
+ this.replace_targets[entry] = toolbar.querySelector(`[data-target=${entry}`);
825
+ }
826
+ for (const entry of ['fill', 'text', 'border']) {
827
+ this.color_bar_elements[entry] = toolbar.querySelector(`[data-color-bar=${entry}]`);
828
+ }
829
+ //
830
+ // unified click handler for toolbar controls
831
+ //
832
+ toolbar.addEventListener('click', event => {
833
+ const target = event.target;
834
+ // the toolbar message used to take "data" for historical
835
+ // reasdons, now it takes inline properties. we can be a little
836
+ // more precise about this, although we'll have to update if
837
+ // we add any new data types.
838
+ const props = {
839
+ format: target.dataset.format,
840
+ scale: target.dataset.scale,
841
+ font_stack: target.dataset.fontStack,
842
+ };
843
+ let command = target?.dataset.command;
844
+ if (command) {
845
+ // we may need to replace an icon in the toolbar
846
+ const replace = target.parentElement?.dataset.replace;
847
+ if (replace) {
848
+ const replace_target = this.replace_targets[replace];
849
+ if (replace_target) {
850
+ replace_target.dataset.command = command;
851
+ replace_target.title = target.title || '';
852
+ }
853
+ }
854
+ // for borders, if we have a cached border color add that to the event data
855
+ if (/^border-/.test(command)) {
856
+ props.color = this.border_color || {};
857
+ }
858
+ switch (command) {
859
+ case 'text-color':
860
+ case 'fill-color':
861
+ props.color = {};
862
+ try {
863
+ props.color = JSON.parse(target.dataset.color || '{}');
864
+ }
865
+ catch (err) {
866
+ console.error(err);
867
+ }
868
+ break;
869
+ case 'set-color':
870
+ // swap command
871
+ command = color_chooser.dataset.colorCommand || '';
872
+ // convert string to color
873
+ props.color = {};
874
+ try {
875
+ props.color = JSON.parse(target.dataset.color || '{}');
876
+ }
877
+ catch (err) {
878
+ console.error(err);
879
+ }
880
+ // cache for later
881
+ if (command === 'border-color') {
882
+ this.border_color = props.color;
883
+ }
884
+ // update color bar
885
+ if (color_chooser.dataset.target) {
886
+ const replace = this.color_bar_elements[color_chooser.dataset.target];
887
+ if (replace) {
888
+ replace.style.setProperty('--treb-color-bar-color', target.style.backgroundColor);
889
+ replace.dataset.color = target.dataset.color || '{}';
890
+ }
891
+ }
892
+ break;
893
+ case 'update-comment':
894
+ props.comment = comment_box.value;
895
+ break;
896
+ }
897
+ sheet.HandleToolbarMessage({
898
+ command,
899
+ ...props,
900
+ });
901
+ }
902
+ });
903
+ // common
904
+ const CreateInputHandler = (selector, handler) => {
905
+ const input = toolbar.querySelector(selector);
906
+ if (input) {
907
+ let cached_value = '';
908
+ input.addEventListener('focusin', () => cached_value = input.value);
909
+ input.addEventListener('keydown', event => {
910
+ switch (event.key) {
911
+ case 'Escape':
912
+ input.value = cached_value;
913
+ sheet.Focus();
914
+ break;
915
+ case 'Enter':
916
+ if (!handler(input.value)) {
917
+ input.value = cached_value;
918
+ sheet.Focus();
919
+ }
920
+ break;
921
+ default:
922
+ return;
923
+ }
924
+ event.stopPropagation();
925
+ event.preventDefault();
926
+ });
927
+ }
928
+ };
929
+ // number format input
930
+ CreateInputHandler('input.treb-number-format', (format) => {
931
+ if (!format) {
932
+ return false;
933
+ }
934
+ sheet.HandleToolbarMessage({
935
+ command: 'number-format',
936
+ format,
937
+ });
938
+ return true;
939
+ });
940
+ // font scale input
941
+ CreateInputHandler('input.treb-font-scale', (value) => {
942
+ const scale = Number(value);
943
+ if (!scale || isNaN(scale)) {
944
+ console.warn('invalid scale value');
945
+ return false;
946
+ }
947
+ sheet.HandleToolbarMessage({
948
+ command: 'font-scale',
949
+ scale,
950
+ });
951
+ return true;
952
+ });
953
+ // color chooser
954
+ const color_input = color_chooser.querySelector('input');
955
+ const color_button = color_chooser.querySelector('input + button');
956
+ color_input.addEventListener('input', (event) => {
957
+ if (event instanceof InputEvent && event.isComposing) {
958
+ return;
959
+ }
960
+ color_button.style.background = color_input.value || '';
961
+ // this is a check for "did it resolve properly"
962
+ const resolved = color_button.style.backgroundColor || '#fff';
963
+ const bytes = Measurement.MeasureColor(resolved);
964
+ const hsl = ColorFunctions.RGBToHSL(bytes[0], bytes[1], bytes[2]);
965
+ // light or dark based on background
966
+ color_button.style.color = (hsl.l > .5) ? '#000' : '#fff';
967
+ // color for command
968
+ color_button.dataset.color = JSON.stringify(color_button.style.backgroundColor ? { text: color_button.style.backgroundColor } : {});
969
+ });
970
+ color_input.addEventListener('keydown', event => {
971
+ if (event.key === 'Enter') {
972
+ event.stopPropagation();
973
+ event.preventDefault();
974
+ color_button.click();
975
+ }
976
+ });
977
+ // --- menus ---------------------------------------------------------------
978
+ // since we are positioning menus with script, they'll get detached
979
+ // if you scroll the toolbar. we could track scrolling, but it makes
980
+ // as much sense to just close any open menu.
981
+ // firefox thinks this is a "scroll linked posiitoning effect". that's
982
+ // not 100% wrong but it's an absurd thing to flag for that warning.
983
+ if (/firefox/i.test(navigator.userAgent)) {
984
+ scroller.addEventListener('scroll', () => {
985
+ if (this.DOM.view && this.DOM.doc?.activeElement instanceof this.DOM.view.HTMLElement) {
986
+ this.DOM.doc.activeElement?.blur();
987
+ }
988
+ });
989
+ }
990
+ else {
991
+ scroller.addEventListener('scroll', () => sheet.Focus());
992
+ }
993
+ // we set up a key listener for the escape key when menus are open, we
994
+ // need to remove it if focus goes out of the toolbar
995
+ let handlers_attached = false;
996
+ const escape_handler = (event) => {
997
+ if (event.key === 'Escape') {
998
+ event.stopPropagation();
999
+ event.preventDefault();
1000
+ Promise.resolve().then(() => sheet.Focus());
1001
+ }
1002
+ };
1003
+ const focusout_handler = (event) => {
1004
+ if (handlers_attached) {
1005
+ if (event.relatedTarget instanceof Node && toolbar.contains(event.relatedTarget)) {
1006
+ return;
1007
+ }
1008
+ toolbar.removeEventListener('keydown', escape_handler);
1009
+ toolbar.removeEventListener('focusout', focusout_handler);
1010
+ handlers_attached = false;
1011
+ }
1012
+ };
1013
+ const PositionMenu = (event) => {
1014
+ // FIXME: because these are situational, move the
1015
+ // lookups/checks outside of this function into the
1016
+ // event handlers
1017
+ let target = event.target;
1018
+ let parent = target?.parentElement;
1019
+ if (target?.classList.contains('treb-menu')) {
1020
+ parent = target;
1021
+ for (const child of Array.from(parent.children)) {
1022
+ if (child.tagName === 'BUTTON') {
1023
+ target = child;
1024
+ break;
1025
+ }
1026
+ }
1027
+ }
1028
+ else if (!parent?.classList.contains('treb-menu')) {
1029
+ return;
1030
+ }
1031
+ // if (parent?.classList.contains('treb-menu'))
1032
+ if (target && parent) {
1033
+ // console.info('positioning');
1034
+ if (!handlers_attached) {
1035
+ toolbar.addEventListener('focusout', focusout_handler);
1036
+ toolbar.addEventListener('keydown', escape_handler);
1037
+ handlers_attached = true;
1038
+ }
1039
+ // we're sharing the color chooser, drop it in to
1040
+ // the target if this is a color menu
1041
+ if (parent.dataset.colorCommand) {
1042
+ color_chooser.querySelector('.treb-default-color')?.setAttribute('title', parent.dataset.defaultColorText || 'Default color');
1043
+ const label = color_chooser.querySelector('.treb-default-color-label');
1044
+ if (label) {
1045
+ label.textContent = parent.dataset.defaultColorText || 'Default color';
1046
+ }
1047
+ parent.appendChild(color_chooser);
1048
+ color_chooser.dataset.colorCommand = parent.dataset.colorCommand;
1049
+ color_chooser.dataset.target = parent.dataset.replaceColor || '';
1050
+ }
1051
+ const menu = parent.querySelector('div');
1052
+ const scroller_rect = scroller.getBoundingClientRect();
1053
+ const target_rect = target.getBoundingClientRect();
1054
+ let { left } = target_rect;
1055
+ // for composite controls, align to the first component
1056
+ // (that only needs to apply on left-aligning)
1057
+ const group = parent.parentElement;
1058
+ if (group?.hasAttribute('composite')) {
1059
+ const element = group.firstElementChild;
1060
+ const rect = element.getBoundingClientRect();
1061
+ left = rect.left;
1062
+ }
1063
+ const menu_rect = menu.getBoundingClientRect();
1064
+ if (parent.classList.contains('treb-submenu')) {
1065
+ menu.style.top = (target_rect.top - menu_rect.height / 2) + 'px';
1066
+ if (left + target_rect.width + 6 + menu_rect.width > scroller_rect.right) {
1067
+ menu.style.left = (left - 6 - menu_rect.width) + 'px';
1068
+ }
1069
+ else {
1070
+ menu.style.left = (left + target_rect.width + 6) + 'px';
1071
+ }
1072
+ }
1073
+ else {
1074
+ menu.style.top = target_rect.bottom + 'px';
1075
+ // right-align if we would overflow the toolbar
1076
+ if (left + menu_rect.width > scroller_rect.right - 6) {
1077
+ menu.style.left = (target_rect.right - menu_rect.width) + 'px';
1078
+ }
1079
+ else {
1080
+ menu.style.left = left + 'px';
1081
+ }
1082
+ }
1083
+ // const focus = menu.querySelector('textarea, input') as HTMLElement;
1084
+ const focus = menu.querySelector('textarea');
1085
+ if (focus) {
1086
+ requestAnimationFrame(() => focus.focus());
1087
+ }
1088
+ }
1089
+ };
1090
+ const format_menu = this.root?.querySelector('.treb-number-format-menu');
1091
+ if (format_menu) {
1092
+ // the first time we call this (now) we want to get the default
1093
+ // colors for text, fill, and border to set buttons.
1094
+ this.UpdateDocumentStyles(sheet, format_menu);
1095
+ this.UpdateSelectionStyle(sheet, toolbar, comment_box);
1096
+ sheet.Subscribe(event => {
1097
+ switch (event.type) {
1098
+ // need to do something with this
1099
+ case 'focus-view':
1100
+ break;
1101
+ case 'data':
1102
+ case 'document-change':
1103
+ case 'load':
1104
+ case 'reset':
1105
+ this.UpdateDocumentStyles(sheet, format_menu);
1106
+ this.UpdateSelectionStyle(sheet, toolbar, comment_box);
1107
+ this.UpdateRevertState(sheet);
1108
+ break;
1109
+ case 'theme-change':
1110
+ this.UpdateDocumentStyles(sheet, format_menu);
1111
+ this.UpdateSelectionStyle(sheet, toolbar, comment_box);
1112
+ break;
1113
+ case 'annotation-selection':
1114
+ case 'selection':
1115
+ this.UpdateSelectionStyle(sheet, toolbar, comment_box);
1116
+ break;
1117
+ }
1118
+ });
1119
+ }
1120
+ const safari = /^((?!chrome|android).)*safari/i.test(navigator.userAgent);
1121
+ // positioning on focusin will catch keyboard and mouse navigation
1122
+ // ...but this won't work on safari. ...
1123
+ toolbar.addEventListener('focusin', event => {
1124
+ PositionMenu(event);
1125
+ });
1126
+ // safari disables focus on buttons for some reason. you can override
1127
+ // that, but does anyone do that? also, what about osx?
1128
+ //
1129
+ // for safari, we'll position on mousedown. this will result in some
1130
+ // extra calls to the position routine but that shouldn't be too
1131
+ // bad. we also need to remove focus on the menu elements we're adding
1132
+ // tab indexes to.
1133
+ if (safari) {
1134
+ const elements = Array.from(toolbar.querySelectorAll('.treb-menu'));
1135
+ for (const element of elements) {
1136
+ element.tabIndex = 0;
1137
+ }
1138
+ toolbar.addEventListener('mousedown', event => {
1139
+ PositionMenu(event);
1140
+ });
1141
+ }
1142
+ }
1143
+ }
1144
+ //# sourceMappingURL=spreadsheet-constructor.js.map