@heycys/gallery 0.1.0 → 0.1.2

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 (465) hide show
  1. package/THIRD-PARTY-NOTICES.md +51 -1
  2. package/browser/editor/components/callout/index.mjs +40 -15
  3. package/browser/editor/components/columns/page.mjs +45 -32
  4. package/browser/editor/components/details/index.mjs +2 -1
  5. package/browser/editor/components/dialog/index.mjs +2 -1
  6. package/browser/editor/components/dialog/page.mjs +0 -18
  7. package/browser/editor/components/divider/index.mjs +1 -1
  8. package/browser/editor/components/embed/index.mjs +2 -2
  9. package/browser/editor/components/figure/page.mjs +10 -1
  10. package/browser/editor/components/file/page.mjs +2 -2
  11. package/browser/editor/components/flowchart/add.mjs +7 -6
  12. package/browser/editor/components/flowchart/page.mjs +1 -1
  13. package/browser/editor/components/heading/index.mjs +2 -0
  14. package/browser/editor/components/heading/page.mjs +6 -0
  15. package/browser/editor/components/highlight/index.mjs +4 -20
  16. package/browser/editor/components/icons.mjs +13 -2
  17. package/browser/editor/components/image/crop.mjs +6 -9
  18. package/browser/editor/components/image/page.mjs +2 -2
  19. package/browser/editor/components/installed/index.mjs +82 -29
  20. package/browser/editor/components/installed/page.mjs +146 -34
  21. package/browser/editor/components/installed/served.mjs +6 -5
  22. package/browser/editor/components/instances.mjs +18 -0
  23. package/browser/editor/components/kit.mjs +3 -0
  24. package/browser/editor/components/list/page.mjs +3 -6
  25. package/browser/editor/components/media/page.mjs +44 -14
  26. package/browser/editor/components/pages.mjs +2 -2
  27. package/browser/editor/components/registry.mjs +68 -33
  28. package/browser/editor/components/section/index.mjs +2 -1
  29. package/browser/editor/components/set-apart.mjs +24 -0
  30. package/browser/editor/components/table/index.mjs +64 -5
  31. package/browser/editor/components/table/page.mjs +30 -19
  32. package/browser/editor/page/annotate/anchors.mjs +4 -3
  33. package/browser/editor/page/annotate/card.mjs +3 -6
  34. package/browser/editor/page/annotate/index.mjs +61 -34
  35. package/browser/editor/page/autosave.mjs +357 -38
  36. package/browser/editor/page/beside.mjs +5 -5
  37. package/browser/editor/page/block-menu/colors.mjs +3 -1
  38. package/browser/editor/page/block-menu/index.mjs +8 -6
  39. package/browser/editor/page/blocks.mjs +16 -7
  40. package/browser/editor/page/board/client.mjs +57 -0
  41. package/browser/editor/page/board/hint.mjs +145 -0
  42. package/browser/editor/page/board/history.mjs +119 -0
  43. package/browser/editor/page/board/index.mjs +970 -0
  44. package/browser/editor/page/board/settings.mjs +209 -0
  45. package/browser/editor/page/caret.mjs +5 -2
  46. package/browser/editor/page/changes/bar.mjs +94 -0
  47. package/browser/editor/page/changes/ghost.mjs +206 -0
  48. package/browser/editor/page/changes/gone-words.mjs +94 -0
  49. package/browser/editor/page/changes/index.mjs +447 -0
  50. package/browser/editor/page/changes/words.mjs +27 -0
  51. package/browser/editor/page/clipboard/import/colors.mjs +3 -3
  52. package/browser/editor/page/clipboard/import/html.mjs +29 -6
  53. package/browser/editor/page/clipboard/import/inline.mjs +32 -0
  54. package/browser/editor/page/clipboard/import/markdown.mjs +58 -13
  55. package/browser/editor/page/clipboard/import/read.mjs +6 -1
  56. package/browser/editor/page/clipboard/import/to-blocks.mjs +44 -12
  57. package/browser/editor/page/clipboard/import/yuque.mjs +622 -0
  58. package/browser/editor/page/clipboard/index.mjs +156 -26
  59. package/browser/editor/page/clipboard/own/blocks.mjs +25 -16
  60. package/browser/editor/page/clipboard/own/chart-keys.mjs +41 -28
  61. package/browser/editor/page/clipboard/own/describe.mjs +16 -7
  62. package/browser/editor/page/clipboard/own/export.mjs +6 -6
  63. package/browser/editor/page/clipboard/own/selection.mjs +3 -3
  64. package/browser/editor/page/clipboard/own/writers.mjs +0 -11
  65. package/browser/editor/page/columns/index.mjs +48 -46
  66. package/browser/editor/page/commit.mjs +98 -25
  67. package/browser/editor/page/conflicts.mjs +13 -33
  68. package/browser/editor/page/convert.mjs +8 -7
  69. package/browser/editor/page/core.mjs +81 -27
  70. package/browser/editor/page/custom-page.mjs +106 -0
  71. package/browser/editor/page/drag/index.mjs +40 -24
  72. package/browser/editor/page/drag/preview.mjs +9 -4
  73. package/browser/editor/page/editor.mjs +120 -28
  74. package/browser/editor/page/emoji-picker/emoji-tab.mjs +22 -13
  75. package/browser/editor/page/emoji-picker/grid.mjs +7 -5
  76. package/browser/editor/page/emoji-picker/icon-tab.mjs +4 -4
  77. package/browser/editor/page/emoji-picker/icons.mjs +0 -1
  78. package/browser/editor/page/emoji-picker/index.mjs +11 -9
  79. package/browser/editor/page/emoji-picker/styles.mjs +156 -2
  80. package/browser/editor/page/emoji-picker/support.mjs +6 -4
  81. package/browser/editor/page/emoji-picker/upload.mjs +14 -13
  82. package/browser/editor/page/fills.mjs +5 -3
  83. package/browser/editor/page/fold/index.mjs +348 -0
  84. package/browser/editor/page/fold/rule.mjs +125 -0
  85. package/browser/editor/page/folded.mjs +23 -0
  86. package/browser/editor/page/format-bar/bar.mjs +2 -1
  87. package/browser/editor/page/format-bar/index.mjs +1 -1
  88. package/browser/editor/page/geometry.mjs +8 -6
  89. package/browser/editor/page/handle/index.mjs +22 -14
  90. package/browser/editor/page/hints/index.mjs +1 -1
  91. package/browser/editor/page/history.mjs +24 -4
  92. package/browser/editor/page/insert/index.mjs +30 -17
  93. package/browser/editor/page/links/index.mjs +5 -3
  94. package/browser/editor/page/links/pages.mjs +27 -9
  95. package/browser/editor/page/long-runs.mjs +75 -0
  96. package/browser/editor/page/look.mjs +69 -6
  97. package/browser/editor/page/margin.mjs +63 -27
  98. package/browser/editor/page/media-menu/index.mjs +6 -7
  99. package/browser/editor/page/menu.mjs +86 -31
  100. package/browser/editor/page/merge.mjs +24 -0
  101. package/browser/editor/page/notices.mjs +3 -3
  102. package/browser/editor/page/offered.mjs +1 -1
  103. package/browser/editor/page/outline/folds.mjs +11 -10
  104. package/browser/editor/page/outline/index.mjs +131 -45
  105. package/browser/editor/page/outline/list.mjs +23 -11
  106. package/browser/editor/page/outline/read.mjs +1 -1
  107. package/browser/editor/page/outline/strip.mjs +7 -1
  108. package/browser/editor/page/page-objects.mjs +13 -2
  109. package/browser/editor/page/panel.mjs +9 -13
  110. package/browser/editor/page/present-links.mjs +11 -2
  111. package/browser/editor/page/resize/index.mjs +42 -29
  112. package/browser/editor/page/selection/delete.mjs +8 -6
  113. package/browser/editor/page/selection/index.mjs +10 -3
  114. package/browser/editor/page/served.mjs +14 -0
  115. package/browser/editor/page/session.mjs +101 -6
  116. package/browser/editor/page/slash-menu/index.mjs +3 -3
  117. package/browser/editor/page/table/cell-bar.mjs +4 -1
  118. package/browser/editor/page/table/cells.mjs +103 -47
  119. package/browser/editor/page/table/icons.mjs +3 -1
  120. package/browser/editor/page/table/index.mjs +40 -16
  121. package/browser/editor/page/table/pictures.mjs +299 -0
  122. package/browser/editor/page/table/views.mjs +150 -0
  123. package/browser/editor/page/table/widths.mjs +9 -4
  124. package/browser/editor/page/text-select/index.mjs +43 -14
  125. package/browser/editor/page/todo-writes.mjs +75 -0
  126. package/browser/editor/page/tooltip.mjs +1 -1
  127. package/browser/editor/page/type-grid.mjs +4 -3
  128. package/browser/editor/page/typing/code-edges.mjs +63 -17
  129. package/browser/editor/page/typing/index.mjs +65 -9
  130. package/browser/editor/page/typing/leave.mjs +1 -1
  131. package/browser/editor/page/ui.mjs +13 -0
  132. package/browser/shared/annotations.mjs +8 -10
  133. package/browser/shared/block-packs.mjs +404 -0
  134. package/browser/shared/board-places.mjs +224 -0
  135. package/browser/shared/card-size.mjs +59 -0
  136. package/browser/shared/code-folds.mjs +5 -1
  137. package/browser/shared/colors.mjs +17 -14
  138. package/browser/shared/component-catalog.mjs +345 -54
  139. package/browser/shared/component-source.mjs +37 -0
  140. package/browser/shared/components/callout.mjs +4 -2
  141. package/browser/shared/components/index.mjs +72 -9
  142. package/browser/shared/components/installed.mjs +110 -8
  143. package/browser/shared/components/page.mjs +22 -3
  144. package/browser/shared/components/state.mjs +5 -1
  145. package/browser/shared/components/table.mjs +1 -1
  146. package/browser/shared/components/text.mjs +2 -2
  147. package/browser/shared/document-look.mjs +183 -0
  148. package/browser/shared/drafts.mjs +432 -0
  149. package/browser/shared/emoji/data/LICENSE-lucide.txt +43 -0
  150. package/browser/shared/emoji/data/README.md +4 -2
  151. package/browser/shared/emoji/data/categories.json +1 -1
  152. package/browser/shared/emoji/data/keywords-en.json +1 -1
  153. package/browser/shared/emoji/data/keywords-zh.json +1 -1
  154. package/browser/shared/emoji/data/names.json +1 -1
  155. package/browser/shared/emoji/data/positions.json +1 -1
  156. package/browser/shared/emoji/data/twemoji-index.json +1 -1
  157. package/browser/shared/emoji/data/twemoji-svg.bin +0 -0
  158. package/browser/shared/emoji/data.mjs +10 -12
  159. package/browser/shared/emoji/emoji.mjs +8 -7
  160. package/browser/shared/emoji/icon-value.mjs +4 -3
  161. package/browser/shared/extension-sidebar.mjs +126 -0
  162. package/browser/shared/extensions.mjs +79 -0
  163. package/browser/shared/file-table.mjs +101 -0
  164. package/browser/shared/html-tree.mjs +11 -5
  165. package/browser/shared/i18n/en.mjs +374 -35
  166. package/browser/shared/json-layout.mjs +47 -0
  167. package/browser/shared/long-runs.mjs +39 -0
  168. package/browser/shared/net-cache.mjs +133 -0
  169. package/browser/shared/net-keys.mjs +32 -0
  170. package/browser/shared/net-policy.mjs +177 -0
  171. package/browser/shared/new-names.mjs +5 -2
  172. package/browser/shared/outline-shape.mjs +128 -0
  173. package/browser/shared/outline.mjs +458 -0
  174. package/browser/shared/pack-manifest.mjs +77 -0
  175. package/browser/shared/page-address.mjs +6 -3
  176. package/browser/shared/page-cards.mjs +308 -0
  177. package/browser/shared/page-links.mjs +69 -6
  178. package/browser/shared/pages.mjs +388 -0
  179. package/browser/shared/paths.mjs +6 -0
  180. package/browser/shared/preferences.mjs +10 -4
  181. package/browser/shared/preview-server.mjs +3 -7
  182. package/browser/shared/session.mjs +13 -5
  183. package/browser/shared/shipped-blocks.mjs +299 -0
  184. package/browser/shared/table-chart.mjs +33 -1
  185. package/browser/shared/todos.mjs +83 -0
  186. package/browser/shared/user-directory.mjs +24 -0
  187. package/browser/shared/versions.mjs +14 -0
  188. package/browser/shared/web-links.mjs +134 -0
  189. package/browser/shared/workspace-columns.mjs +120 -0
  190. package/browser/shared/workspace-look.mjs +91 -0
  191. package/browser/shared/workspace-name.mjs +154 -0
  192. package/browser/shared/workspace-query.mjs +125 -0
  193. package/browser/shared/workspace-registry.mjs +272 -0
  194. package/browser/shared/workspace.mjs +171 -20
  195. package/browser/shared/zoom.mjs +5 -5
  196. package/dist/chunk-2NRBY6AJ.mjs +2 -0
  197. package/dist/chunk-32ZUEFZ7.mjs +2 -0
  198. package/dist/chunk-35NQ4PLQ.mjs +2 -0
  199. package/dist/chunk-3KJHLHUO.mjs +2 -0
  200. package/dist/chunk-3NJACR4W.mjs +2 -0
  201. package/dist/chunk-4AV456RQ.mjs +2 -0
  202. package/dist/chunk-4OZWXZE5.mjs +5 -0
  203. package/dist/chunk-5XYHDBJ5.mjs +2 -0
  204. package/dist/chunk-5ZJA7CXT.mjs +2 -0
  205. package/dist/chunk-6A53MZYZ.mjs +2 -0
  206. package/dist/chunk-6EXH3ORZ.mjs +166 -0
  207. package/dist/chunk-6EZ7FNIK.mjs +3 -0
  208. package/dist/{chunk-UXUK4PMC.mjs → chunk-6QBHU4DF.mjs} +1 -1
  209. package/dist/{chunk-6U2SLSDN.mjs → chunk-6VTU6KEO.mjs} +1 -1
  210. package/dist/chunk-B4P2CM2J.mjs +3 -0
  211. package/dist/chunk-BPL64HGA.mjs +4 -0
  212. package/dist/chunk-BVEFGE4B.mjs +2 -0
  213. package/dist/chunk-BZ5RAF7L.mjs +2 -0
  214. package/dist/chunk-CRJEG7MT.mjs +2 -0
  215. package/dist/{chunk-B3VTYBYR.mjs → chunk-D4CKRD3V.mjs} +91 -91
  216. package/dist/chunk-D4EURAX4.mjs +4 -0
  217. package/dist/chunk-DQCE7TJY.mjs +5 -0
  218. package/dist/chunk-DR73Y2UJ.mjs +3 -0
  219. package/dist/{chunk-TMYZB6AV.mjs → chunk-EKNHM3P4.mjs} +1 -1
  220. package/dist/{chunk-DB4WKGYF.mjs → chunk-ERLAIBOA.mjs} +2 -2
  221. package/dist/chunk-EURLTOTZ.mjs +4 -0
  222. package/dist/chunk-FJYN7RTH.mjs +4 -0
  223. package/dist/chunk-FWNRPMCJ.mjs +12 -0
  224. package/dist/chunk-FWW4CSAZ.mjs +2 -0
  225. package/dist/{chunk-2B5E4CDJ.mjs → chunk-GPIWQ4X4.mjs} +1 -1
  226. package/dist/chunk-GY3FAUVM.mjs +2 -0
  227. package/dist/chunk-HLYV7RIH.mjs +2 -0
  228. package/dist/chunk-HMYTM3GT.mjs +15 -0
  229. package/dist/chunk-IA4PSIMD.mjs +2 -0
  230. package/dist/chunk-JEUK3ZO7.mjs +2 -0
  231. package/dist/chunk-JVHHHGEA.mjs +3 -0
  232. package/dist/chunk-KTKHRC6H.mjs +2 -0
  233. package/dist/chunk-L7UP52JO.mjs +2 -0
  234. package/dist/chunk-MHW7ZKOU.mjs +2 -0
  235. package/dist/chunk-N76HWBA3.mjs +10 -0
  236. package/dist/chunk-N7AZZLGT.mjs +548 -0
  237. package/dist/chunk-NAMN3RAF.mjs +2 -0
  238. package/dist/{chunk-YXAUQPVK.mjs → chunk-NFMCP2HI.mjs} +3 -3
  239. package/dist/chunk-NG375ILQ.mjs +2 -0
  240. package/dist/chunk-NVRNLK25.mjs +6 -0
  241. package/dist/chunk-NWFBE2YA.mjs +2 -0
  242. package/dist/chunk-NWR2LT5B.mjs +2 -0
  243. package/dist/chunk-OJKMINIU.mjs +20 -0
  244. package/dist/chunk-OUUP3WKT.mjs +2 -0
  245. package/dist/chunk-OW5NWPOJ.mjs +10 -0
  246. package/dist/chunk-PAREWQGB.mjs +4 -0
  247. package/dist/chunk-POQSE4C2.mjs +2 -0
  248. package/dist/chunk-PUOQ65NC.mjs +2 -0
  249. package/dist/{chunk-Z52HTUW7.mjs → chunk-PVER7LSC.mjs} +2 -2
  250. package/dist/chunk-PZDLJJTJ.mjs +3 -0
  251. package/dist/chunk-Q47PLKIJ.mjs +15 -0
  252. package/dist/chunk-Q4UEPUWF.mjs +2 -0
  253. package/dist/chunk-QKXMPUXC.mjs +2 -0
  254. package/dist/chunk-QOUEFUCH.mjs +16 -0
  255. package/dist/chunk-RFDZXFJF.mjs +13 -0
  256. package/dist/chunk-RKPWLGZ3.mjs +4 -0
  257. package/dist/chunk-RMECZA2K.mjs +2 -0
  258. package/dist/{chunk-EUX7IC5J.mjs → chunk-SQ6Y2ZMA.mjs} +2 -2
  259. package/dist/chunk-SX4LJYT6.mjs +8 -0
  260. package/dist/chunk-SXHBYZST.mjs +16 -0
  261. package/dist/chunk-TANZRINB.mjs +2 -0
  262. package/dist/chunk-TEZAWDSQ.mjs +2 -0
  263. package/dist/chunk-UBBRTJ2R.mjs +24 -0
  264. package/dist/chunk-UFNYFFKO.mjs +20 -0
  265. package/dist/chunk-UGWYKHBL.mjs +170 -0
  266. package/dist/chunk-UKSHDZZ6.mjs +2 -0
  267. package/dist/chunk-UMHUSOPJ.mjs +2 -0
  268. package/dist/chunk-UNOYVIYR.mjs +2 -0
  269. package/dist/chunk-V6RIYQZZ.mjs +4 -0
  270. package/dist/chunk-VJPFVNNW.mjs +15 -0
  271. package/dist/chunk-VS3ZMVGX.mjs +5 -0
  272. package/dist/chunk-VTKNEYT3.mjs +6 -0
  273. package/dist/chunk-VXACTLO3.mjs +3 -0
  274. package/dist/chunk-W3BGBJQW.mjs +2 -0
  275. package/dist/chunk-YI43RG4P.mjs +2 -0
  276. package/dist/chunk-YQGT4AB2.mjs +6 -0
  277. package/dist/chunk-ZB4H7ZN4.mjs +2 -0
  278. package/dist/{chunk-ACOPDCNB.mjs → chunk-ZHEHPMBK.mjs} +1 -1
  279. package/dist/chunk-ZTHICSSF.mjs +2 -0
  280. package/dist/chunk-ZUNVAXLH.mjs +2 -0
  281. package/dist/chunk-ZWPMCK7P.mjs +2 -0
  282. package/dist/cli.mjs +1 -1
  283. package/dist/server.mjs +1 -1
  284. package/dist/{chunk-EVJ3BX3M.mjs → update-fetch.mjs} +1 -1
  285. package/dist/worker.mjs +1 -1
  286. package/kit/board.css +95 -0
  287. package/kit/board.js +250 -0
  288. package/kit/charts.js +5 -71
  289. package/kit/code.js +14 -14
  290. package/kit/math.js +18 -2
  291. package/kit/report.css +500 -151
  292. package/kit/runtime.js +1720 -170
  293. package/kit/state.js +10 -1
  294. package/kit/tables.js +172 -37
  295. package/kit/ui.js +166 -27
  296. package/package.json +2 -1
  297. package/packs/gallery/card/component.json +14 -0
  298. package/packs/gallery/card/example.html +10 -0
  299. package/packs/gallery/card/preview.svg +1 -0
  300. package/packs/gallery/card/style.css +6 -0
  301. package/packs/gallery/card/template.html +6 -0
  302. package/packs/gallery/card/writing.md +14 -0
  303. package/packs/gallery/chart-card/component.json +15 -0
  304. package/packs/gallery/chart-card/example.html +14 -0
  305. package/packs/gallery/chart-card/kit.js +130 -0
  306. package/packs/gallery/chart-card/preview.svg +1 -0
  307. package/packs/gallery/chart-card/style.css +42 -0
  308. package/packs/gallery/chart-card/template.html +13 -0
  309. package/packs/gallery/chart-card/writing.md +20 -0
  310. package/packs/gallery/chart-view/component.json +20 -0
  311. package/packs/gallery/chart-view/example.html +13 -0
  312. package/packs/gallery/chart-view/kit.js +355 -0
  313. package/packs/gallery/chart-view/preview.svg +1 -0
  314. package/packs/gallery/chart-view/style.css +94 -0
  315. package/packs/gallery/chart-view/template.html +3 -0
  316. package/packs/gallery/chart-view/writing.md +22 -0
  317. package/packs/gallery/countdown/component.json +18 -0
  318. package/packs/gallery/countdown/example.html +3 -0
  319. package/packs/gallery/countdown/kit.js +156 -0
  320. package/packs/gallery/countdown/preview.svg +1 -0
  321. package/packs/gallery/countdown/style.css +130 -0
  322. package/packs/gallery/countdown/template.html +3 -0
  323. package/packs/gallery/countdown/writing.md +22 -0
  324. package/packs/gallery/habit/component.json +14 -0
  325. package/packs/gallery/habit/example.html +3 -0
  326. package/packs/gallery/habit/kit.js +295 -0
  327. package/packs/gallery/habit/preview.svg +1 -0
  328. package/packs/gallery/habit/style.css +246 -0
  329. package/packs/gallery/habit/template.html +3 -0
  330. package/packs/gallery/habit/writing.md +21 -0
  331. package/packs/gallery/heatmap/component.json +18 -0
  332. package/packs/gallery/heatmap/example.html +3 -0
  333. package/packs/gallery/heatmap/kit.js +351 -0
  334. package/packs/gallery/heatmap/preview.svg +1 -0
  335. package/packs/gallery/heatmap/style.css +201 -0
  336. package/packs/gallery/heatmap/template.html +3 -0
  337. package/packs/gallery/heatmap/writing.md +21 -0
  338. package/packs/gallery/kanban/component.json +18 -0
  339. package/packs/gallery/kanban/example.html +12 -0
  340. package/packs/gallery/kanban/kit.js +540 -0
  341. package/packs/gallery/kanban/preview.svg +1 -0
  342. package/packs/gallery/kanban/style.css +212 -0
  343. package/packs/gallery/kanban/template.html +3 -0
  344. package/packs/gallery/kanban/writing.md +20 -0
  345. package/packs/gallery/metric/component.json +22 -0
  346. package/packs/gallery/metric/example.html +15 -0
  347. package/packs/gallery/metric/kit.js +248 -0
  348. package/packs/gallery/metric/preview.svg +1 -0
  349. package/packs/gallery/metric/style.css +92 -0
  350. package/packs/gallery/metric/template.html +3 -0
  351. package/packs/gallery/metric/writing.md +23 -0
  352. package/packs/gallery/note/component.json +14 -0
  353. package/packs/gallery/note/example.html +3 -0
  354. package/packs/gallery/note/kit.js +102 -0
  355. package/packs/gallery/note/preview.svg +1 -0
  356. package/packs/gallery/note/style.css +76 -0
  357. package/packs/gallery/note/template.html +3 -0
  358. package/packs/gallery/note/writing.md +18 -0
  359. package/packs/gallery/pack.json +8 -0
  360. package/packs/gallery/recent/component.json +13 -0
  361. package/packs/gallery/recent/example.html +1 -0
  362. package/packs/gallery/recent/kit.js +238 -0
  363. package/packs/gallery/recent/preview.svg +1 -0
  364. package/packs/gallery/recent/style.css +158 -0
  365. package/packs/gallery/recent/template.html +1 -0
  366. package/packs/gallery/recent/writing.md +15 -0
  367. package/packs/gallery/static/component.json +13 -0
  368. package/packs/gallery/static/example.html +11 -0
  369. package/packs/gallery/static/preview.svg +1 -0
  370. package/packs/gallery/static/style.css +138 -0
  371. package/packs/gallery/static/template.html +1 -0
  372. package/packs/gallery/static/writing.md +18 -0
  373. package/packs/gallery/stats/component.json +13 -0
  374. package/packs/gallery/stats/example.html +1 -0
  375. package/packs/gallery/stats/kit.js +166 -0
  376. package/packs/gallery/stats/preview.svg +1 -0
  377. package/packs/gallery/stats/style.css +151 -0
  378. package/packs/gallery/stats/template.html +1 -0
  379. package/packs/gallery/stats/writing.md +11 -0
  380. package/packs/gallery/today/component.json +12 -0
  381. package/packs/gallery/today/example.html +1 -0
  382. package/packs/gallery/today/kit.js +185 -0
  383. package/packs/gallery/today/preview.svg +1 -0
  384. package/packs/gallery/today/style.css +120 -0
  385. package/packs/gallery/today/template.html +1 -0
  386. package/packs/gallery/today/writing.md +14 -0
  387. package/packs/gallery/todos/component.json +19 -0
  388. package/packs/gallery/todos/example.html +3 -0
  389. package/packs/gallery/todos/kit.js +342 -0
  390. package/packs/gallery/todos/preview.svg +1 -0
  391. package/packs/gallery/todos/style.css +267 -0
  392. package/packs/gallery/todos/template.html +3 -0
  393. package/packs/gallery/todos/writing.md +30 -0
  394. package/packs/gallery/weather/component.json +19 -0
  395. package/packs/gallery/weather/example.html +3 -0
  396. package/packs/gallery/weather/kit.js +312 -0
  397. package/packs/gallery/weather/preview.svg +1 -0
  398. package/packs/gallery/weather/style.css +258 -0
  399. package/packs/gallery/weather/template.html +3 -0
  400. package/packs/gallery/weather/writing.md +26 -0
  401. package/packs/gallery-soft/pack.json +8 -0
  402. package/release.json +13 -11
  403. package/sdk/doc-kit.d.ts +404 -7
  404. package/sdk/doc-state.d.ts +2 -0
  405. package/skill/SKILL.md +71 -26
  406. package/skill/references/block-script.md +140 -0
  407. package/skill/references/building-blocks.md +257 -0
  408. package/skill/references/example-report.html +1 -1
  409. package/skill/references/extensions.md +59 -0
  410. package/skill/references/pages-and-data.md +221 -0
  411. package/skill/references/writing-html.md +9 -7
  412. package/skill/sdk/doc-kit.d.ts +404 -7
  413. package/skill/sdk/doc-state.d.ts +2 -0
  414. package/web/assets/index-BK2e_07w.js +13 -0
  415. package/web/assets/index-CWFI83mF.css +1 -0
  416. package/web/index.html +2 -2
  417. package/browser/editor/components/callout/page.mjs +0 -13
  418. package/dist/chunk-2PBALTR3.mjs +0 -57
  419. package/dist/chunk-3LA3EMDE.mjs +0 -15
  420. package/dist/chunk-5FRMCDPY.mjs +0 -16
  421. package/dist/chunk-5LEK2CBS.mjs +0 -2
  422. package/dist/chunk-5OFN5AHC.mjs +0 -2
  423. package/dist/chunk-5SIYS5HN.mjs +0 -2
  424. package/dist/chunk-5TEK3RAD.mjs +0 -2
  425. package/dist/chunk-6CYG3Z4V.mjs +0 -2
  426. package/dist/chunk-7GHT2UCA.mjs +0 -15
  427. package/dist/chunk-7QQBR7PB.mjs +0 -2
  428. package/dist/chunk-ATCJYAR4.mjs +0 -2
  429. package/dist/chunk-C7HWOBIF.mjs +0 -2
  430. package/dist/chunk-E7VYDG2X.mjs +0 -2
  431. package/dist/chunk-EZY3WC6Z.mjs +0 -15
  432. package/dist/chunk-FQGQH4KM.mjs +0 -2
  433. package/dist/chunk-G7TOXONE.mjs +0 -6
  434. package/dist/chunk-GPF4YWWB.mjs +0 -9
  435. package/dist/chunk-GYQV7Y4J.mjs +0 -120
  436. package/dist/chunk-HMHK3EQ6.mjs +0 -2
  437. package/dist/chunk-HQQMJCQJ.mjs +0 -10
  438. package/dist/chunk-IERUOGC3.mjs +0 -6
  439. package/dist/chunk-ITNLYXXV.mjs +0 -3
  440. package/dist/chunk-L4DVONOG.mjs +0 -2
  441. package/dist/chunk-LAE5NQ4B.mjs +0 -2
  442. package/dist/chunk-LC7YNQFG.mjs +0 -2
  443. package/dist/chunk-LHTFLRB6.mjs +0 -4
  444. package/dist/chunk-NFIBI4IP.mjs +0 -26
  445. package/dist/chunk-NSKUTQ5J.mjs +0 -5
  446. package/dist/chunk-O52JMOCZ.mjs +0 -2
  447. package/dist/chunk-P2CAZPDP.mjs +0 -3
  448. package/dist/chunk-QMQUXTU4.mjs +0 -12
  449. package/dist/chunk-QVWVFC5K.mjs +0 -6
  450. package/dist/chunk-QYKCJ7FG.mjs +0 -8
  451. package/dist/chunk-QZY6Q64C.mjs +0 -2
  452. package/dist/chunk-TDQP3DKQ.mjs +0 -10
  453. package/dist/chunk-TX6JH7TR.mjs +0 -2
  454. package/dist/chunk-UNUEWH4S.mjs +0 -2
  455. package/dist/chunk-V4CPWKMZ.mjs +0 -2
  456. package/dist/chunk-VACRB2NE.mjs +0 -3
  457. package/dist/chunk-W63L7367.mjs +0 -7
  458. package/dist/chunk-W7CXPCRV.mjs +0 -6
  459. package/dist/chunk-XINNG4F2.mjs +0 -4
  460. package/dist/chunk-YL2DPWVS.mjs +0 -4
  461. package/dist/chunk-YZ5Z6H4W.mjs +0 -4
  462. package/dist/chunk-ZBIM6ARY.mjs +0 -216
  463. package/skill/references/building-components.md +0 -327
  464. package/web/assets/index-B6Ai3wsa.js +0 -13
  465. package/web/assets/index-SYPC3EZy.css +0 -1
@@ -1,13 +1,13 @@
1
1
  import { escapeText } from "../../../shared/escape.mjs";
2
2
  import { BLOCK_COLORS, cellColorOf, colorLook } from "../../components/colors.mjs";
3
- import { CELLS_MIME as MIME, CELL_BOLD, OLD_CELLS_MIME, cellsData } from "../../components/table/index.mjs";
3
+ import { CELLS_MIME as MIME, CELL_BOLD, OLD_CELLS_MIME, pictureFile } from "../../components/table/index.mjs";
4
4
  import { alignItems, alignLook } from "./aligns.mjs";
5
5
  import { insertColumn, insertRow, tableParts, tableSlots, tableState } from "../../components/table/page.mjs";
6
6
  import { atEdge, editable } from "../caret.mjs";
7
7
  import { pastedLines, serializeInner } from "../core.mjs";
8
8
  import { formulaMaker, loadKatex } from "../formula/index.mjs";
9
9
  import { FORMAT_KEYS } from "../format-bar/index.mjs";
10
- import { formatRange, markValue } from "../marks.mjs";
10
+ import { formatRange, markValue, rangeAt, rangeOffsets } from "../marks.mjs";
11
11
  import { gestureLock } from "../gesture.mjs";
12
12
  import { addStyle } from "../ui.mjs";
13
13
  import { createCellBar } from "./cell-bar.mjs";
@@ -15,7 +15,7 @@ import { createCellLists } from "./lists.mjs";
15
15
  import { t } from "../../../shared/i18n/index.mjs";
16
16
 
17
17
  // Selected cells of a table and the keys in a table (notion-lite's, src/blocks/table/edit/; the
18
- // rules in table-math-plan-2026-10-18.md), with the cells' bar (cell-bar.mjs) over them.
18
+ // rules in notes/plans/table-math-plan-2026-10-18.md), with the cells' bar (cell-bar.mjs) over them.
19
19
  //
20
20
  // - Selecting: a press in a cell dragged into another selects the cells between (the text selection
21
21
  // goes; back in the first, that one cell, no caret); Shift+click from the selection's anchor (or
@@ -31,9 +31,12 @@ import { t } from "../../../shared/i18n/index.mjs";
31
31
  // a typed character goes at the end of the last cell, editing it; Ctrl+D fills down (copies rows or
32
32
  // columns), Ctrl+R right; Ctrl+B / I / U / E and Ctrl+Shift+S format whole cells.
33
33
  // - Copied, cells are the page's own (their inline HTML), an HTML table and lines of tab-separated
34
- // text; pasted onto selected cells, the page's own, another program's table (its words) or lines
35
- // of tab-separated text fill them from the top left (repeated over a selection a whole number of
36
- // times larger), rows and columns put in where they overflow; one undo step.
34
+ // text (a cell in quotes holding its lines, as Excel writes one); pasted onto selected cells or with
35
+ // the caret in one, what the clipboard holds as cells (clipboard/ cellsOf: the page's own, another
36
+ // program's table with its marks and pictures, a Markdown table, tab-separated lines) fills them
37
+ // from the top left or the caret's cell (repeated over a selection a whole number of times larger),
38
+ // rows and columns put in where they overflow; one undo step. With the caret in a cell a single
39
+ // value is the editor's paste at the caret (but one holding a picture: pictures.mjs).
37
40
  // A cell's color (one, as a block's: components/colors.mjs) and alignment are its classes (its look:
38
41
  // components/table/index.mjs); its text changes are the editor's (struct, history.mjs). Where cells
39
42
  // are merged (shared/table-slots.mjs), Tab goes from cell to cell, the arrows and Enter step
@@ -407,6 +410,17 @@ export function createCells(tools) {
407
410
 
408
411
  // A cell's inline HTML as copied (a locked cell's words alone: what a script drew is not its text).
409
412
  const htmlOf = (cell) => (writable(cell) ? serializeInner(cell) : escapeText(cell.textContent));
413
+ // A cell's words as text: its lines (its line breaks, its list's items) apart, a picture its alt.
414
+ const textOf = (cell) => {
415
+ const copy = cell.cloneNode(true);
416
+ copy.querySelectorAll("[data-doc-dev]").forEach((node) => node.remove());
417
+ copy.querySelectorAll("br").forEach((node) => node.replaceWith("\n"));
418
+ copy.querySelectorAll("li").forEach((node, index) => index > 0 && node.prepend("\n"));
419
+ copy.querySelectorAll("img").forEach((node) => node.replaceWith(node.getAttribute("alt") ?? ""));
420
+ return copy.textContent.replace(/[ \t]*\n[ \t]*/g, "\n").trim();
421
+ };
422
+ // A cell of tab-separated text as Excel writes one: in quotes when it holds a tab, a line break or a quote, its quotes doubled.
423
+ const tsvCell = (text) => (/[\t\n"]/.test(text) ? `"${text.replace(/"/g, '""')}"` : text);
410
424
 
411
425
  function copy(event) {
412
426
  const sel = tools.sel;
@@ -426,64 +440,108 @@ export function createCells(tools) {
426
440
  }
427
441
  }
428
442
  const html = grid.map((row) => row.map((cell) => (cell ? htmlOf(cell) : "")));
429
- const payload = JSON.stringify({ v: 1, cells: html });
443
+ // The report it was copied from: a paste in another one copies its pictures' files.
444
+ const payload = JSON.stringify({ v: 1, cells: html, report: document.querySelector(".doc-page")?.dataset.docId ?? null });
430
445
  event.clipboardData.setData(MIME, payload);
431
446
  event.clipboardData.setData(OLD_CELLS_MIME, payload); // a page of the old version (before 2026-10-26) reads this one
432
- event.clipboardData.setData("text/html", `<table>${html.map((row) => `<tr>${row.map((cell) => `<td>${cell}</td>`).join("")}</tr>`).join("")}</table>`);
433
- event.clipboardData.setData("text/plain", grid.map((row) => row.map((cell) => (cell?.textContent ?? "").replace(/[\t\n]+/g, " ")).join("\t")).join("\n"));
447
+ // For other programs (Excel, Google Sheets, another editor): an HTML table, its pictures where the
448
+ // server serves them (an address of this computer), and tab-separated text.
449
+ const shown = (cell) => (cell ? htmlOf(cell).replace(/<img src="(assets\/[^"]+)"/g, (all, file) => `<img src="${escapeText(new URL(cell.querySelector(`img[data-ge-src="${file}"]`)?.getAttribute("src") ?? file, location.href).href)}"`) : "");
450
+ event.clipboardData.setData("text/html", `<table>${grid.map((row) => `<tr>${row.map((cell) => `<td>${shown(cell)}</td>`).join("")}</tr>`).join("")}</table>`);
451
+ event.clipboardData.setData("text/plain", grid.map((row) => row.map((cell) => tsvCell(cell ? textOf(cell) : "")).join("\t")).join("\n"));
434
452
  if (event.type === "cut") clearCells(tools, grid.flat().filter(Boolean));
435
453
  else tools.say(t("已复制 {0} 格", grid.length * grid[0].length));
436
454
  }
437
455
  document.addEventListener("copy", copy, true);
438
456
  document.addEventListener("cut", copy, true);
439
457
 
440
- // What is pasted, as rows of cells ({ html } the page's own, { text } another program's), or null:
441
- // the page's cells, its text, table or blocks with their marks (blocks one cell of their words, no
442
- // list's marker or Markdown: tools.ownCells), another program's table, tab-separated lines or text.
443
- function gridOf(data) {
444
- try {
445
- const own = JSON.parse(cellsData(data) || "null");
446
- if (Array.isArray(own?.cells) && own.cells.length > 0 && own.cells.every((row) => Array.isArray(row) && row.length > 0 && row.every((html) => typeof html === "string"))) {
447
- return own.cells.map((row) => row.map((html) => ({ html })));
448
- }
449
- } catch {
450
- // not the page's own
451
- }
452
- const rows = tools.ownCells(data);
453
- if (rows) return rows.map((row) => row.map((html) => ({ html })));
454
- const html = data.getData("text/html");
455
- const table = html ? new DOMParser().parseFromString(html, "text/html").querySelector("table") : null;
456
- if (table?.rows.length) return [...table.rows].map((row) => [...row.cells].map((cell) => ({ text: cell.textContent.replace(/\s+/g, " ").trim() })));
457
- const text = (data.getData("text/plain") || "").replace(/\r\n?/g, "\n").replace(/\n$/, "");
458
- const lines = text.split("\n");
459
- if (lines.length > 1) {
460
- const width = lines[0].split("\t").length;
461
- if (width > 1 && lines.every((line) => line.split("\t").length === width)) return lines.map((line) => line.split("\t").map((part) => ({ text: part })));
462
- }
463
- return text ? [[{ text: text.replace(/\s*\n\s*/g, " ") }]] : null;
458
+ // The cell the caret (or a selection within it) is in, where a paste goes (`target`: the event's,
459
+ // the cell or in it), in a table the tools manage, with where it is: { unit, at, cell }, or null.
460
+ function caretCell(target) {
461
+ const selection = getSelection();
462
+ const node = selection.rangeCount ? selection.getRangeAt(0).commonAncestorContainer : null;
463
+ const cell = (node?.nodeType === 1 ? node : node?.parentElement)?.closest?.("td, th");
464
+ const unit = cell && writable(cell) && cell.contains(target) ? tools.tableAt(cell) : null;
465
+ const at = unit ? tools.placeOf(tableSlots(unit), cell) : null;
466
+ return at ? { unit, at, cell } : null;
464
467
  }
468
+ // Whether a pasted cell holds nothing: no words, no picture.
469
+ const blank = (html) => !html.includes("<img") && !html.replace(/<[^>]*>/g, "").replace(/&nbsp;/g, " ").trim();
465
470
 
471
+ // A paste into the cells (notion-lite's 872952, the user's 2026-11-09: cells pasted with the caret in
472
+ // a cell are cells, not one cell's text): what the clipboard holds as cells (tools.cellsOf: the
473
+ // page's own, another program's table, a Markdown table, tab-separated lines, else its text) goes
474
+ // from the selected cells' top left, or the caret's cell. With the caret in a cell, a single value
475
+ // is the editor's paste at the caret (its marks, an address a link: clipboard/), but one holding a
476
+ // picture, which goes in at the caret here (its file copied first); with cells selected, it fills
477
+ // them (notion-lite's), as do picture files pasted on them (in the first one).
466
478
  function paste(event) {
467
479
  const sel = tools.sel;
468
- if (!sel || sel.editing || !tools.active() || !sel.unit.isConnected) return;
480
+ if (!tools.active()) return;
481
+ const caret = !sel || sel.editing ? caretCell(event.target) : null;
482
+ if (!(caret || (sel && !sel.editing && sel.unit.isConnected))) return;
483
+ const data = event.clipboardData;
484
+ const pasted = data ? tools.cellsOf(data) : null;
485
+ const many = pasted && (pasted.rows.length > 1 || pasted.rows[0].length > 1);
486
+ const files = [...(data?.files ?? [])].filter((file) => /^image\//.test(file.type));
487
+ if (caret && !many && !(pasted?.rows[0][0].includes("<img") && !files.length)) return; // the editor's
469
488
  event.preventDefault();
470
489
  event.stopImmediatePropagation();
471
- const grid = gridOf(event.clipboardData);
472
- if (!grid) return;
473
- // Formulas in what is pasted are drawn at once, KaTeX loaded first where the page has none yet.
474
- if (grid.some((row) => row.some((cell) => cell.html?.includes("doc-math-inline")))) loadKatex().then(() => pasteGrid(sel, grid, formulaMaker()));
475
- else pasteGrid(sel, grid, null);
490
+ const target = caret ? { unit: caret.unit, type: "cell", anchor: caret.at, focus: caret.at, editing: false } : sel;
491
+ if (!pasted && !files.length) return;
492
+ const offsets = caret && !many ? rangeOffsets(caret.cell, getSelection().getRangeAt(0)) : null;
493
+ (async () => {
494
+ let rows = pasted?.rows;
495
+ let found = new Map();
496
+ if (!rows) {
497
+ // Picture files on selected cells: the first one's pictures.
498
+ const made = await tools.pictures.fromFiles(files);
499
+ if (!made.length) return;
500
+ rows = [[made.map((img) => `<img src="${pictureFile(img)}" alt="">`).join("")]];
501
+ made.forEach((img) => found.set(pictureFile(img), { path: pictureFile(img) }));
502
+ } else found = await tools.pictures.resolve(rows.flat(), pasted.from);
503
+ // Formulas in what is pasted are drawn at once, KaTeX loaded first where the page has none yet.
504
+ const formula = rows.some((row) => row.some((html) => html.includes("doc-math-inline"))) && (await loadKatex()) ? formulaMaker() : null;
505
+ const lines = (html) => {
506
+ const made = pastedLines(document, html, { links: true, formula, picture: tools.pictures.maker(found) });
507
+ return made.flatMap((line, index) => (index > 0 ? [document.createElement("br"), ...line] : line));
508
+ };
509
+ if (offsets) atCaret(caret, offsets, lines(rows[0][0]));
510
+ else pasteGrid(target, rows, lines);
511
+ })();
512
+ }
513
+
514
+ // A value holding a picture pasted at the caret in a cell (its file copied first): in at the caret,
515
+ // one undo step, the caret after it.
516
+ function atCaret({ unit, cell }, offsets, nodes) {
517
+ if (!cell.isConnected || nodes.length === 0) return;
518
+ let last = null;
519
+ const made = tools.change(unit, () => {
520
+ const range = rangeAt(cell, offsets);
521
+ range.deleteContents();
522
+ const fragment = document.createDocumentFragment();
523
+ fragment.append(...nodes);
524
+ last = nodes.at(-1);
525
+ range.insertNode(fragment);
526
+ return true;
527
+ }, null, [cell]);
528
+ if (made === null || !last?.isConnected) return;
529
+ const range = document.createRange();
530
+ range.setStartAfter(last);
531
+ range.collapse(true);
532
+ getSelection().removeAllRanges();
533
+ getSelection().addRange(range);
476
534
  }
477
535
 
478
- function pasteGrid(sel, pasted, formula) {
536
+ // `pasted`: rows of cells' inline HTML; `lines(html)`: a cell's nodes of one of them.
537
+ function pasteGrid(sel, pasted, lines) {
479
538
  if (!sel.unit.isConnected) return;
480
539
  let grid = pasted;
481
540
  // Its empty last rows and columns go.
482
- const empty = (cell) => !(cell.html ?? cell.text).replace(/<[^>]*>/g, "").trim();
483
- while (grid.length > 1 && grid.at(-1).every(empty)) grid = grid.slice(0, -1);
541
+ while (grid.length > 1 && grid.at(-1).every(blank)) grid = grid.slice(0, -1);
484
542
  const width = Math.max(...grid.map((row) => row.length));
485
- grid = grid.map((row) => [...row, ...Array.from({ length: width - row.length }, () => ({ text: "" }))]);
486
- while (grid[0].length > 1 && grid.every((row) => empty(row.at(-1)))) grid = grid.map((row) => row.slice(0, -1));
543
+ grid = grid.map((row) => [...row, ...Array.from({ length: width - row.length }, () => "")]);
544
+ while (grid[0].length > 1 && grid.every((row) => blank(row.at(-1)))) grid = grid.map((row) => row.slice(0, -1));
487
545
  const { unit } = sel;
488
546
  const { r0, r1, c0, c1 } = tools.bounds(sel);
489
547
  const times = [Math.max(1, Math.floor((r1 - r0 + 1) / grid.length)), Math.max(1, Math.floor((c1 - c0 + 1) / grid[0].length))];
@@ -504,9 +562,7 @@ export function createCells(tools) {
504
562
  // A merged cell takes what goes in its top left slot.
505
563
  const place = tools.placeOf(slotsNow, cell);
506
564
  if (!cell || !writable(cell) || place[0] !== r0 + r || place[1] !== c0 + c) continue;
507
- const from = grid[r % grid.length][c % grid[0].length];
508
- if (from.html !== undefined) cell.replaceChildren(...pastedLines(document, from.html, { links: true, formula }).flatMap((line, index) => (index > 0 ? [document.createTextNode(" "), ...line] : line)));
509
- else cell.textContent = from.text;
565
+ cell.replaceChildren(...lines(grid[r % grid.length][c % grid[0].length]));
510
566
  }
511
567
  }
512
568
  return true;
@@ -20,7 +20,7 @@ export const TABLE_ICONS = {
20
20
  // A row and a column taken out: the table with the row (column) crossed.
21
21
  removeRow: svg('<rect x="3.25" y="4.25" width="13.5" height="11.5" rx="2"/><path d="M3.25 8.25h13.5M3.25 11.75h13.5"/><path d="m8.25 8.75 3.5 2.5M11.75 8.75l-3.5 2.5"/>'),
22
22
  removeColumn: svg('<rect x="3.25" y="4.25" width="13.5" height="11.5" rx="2"/><path d="M8.25 4.25v11.5M11.75 4.25v11.5"/><path d="m8.75 8.25 2.5 3.5M11.25 8.25l-2.5 3.5"/>'),
23
- // 均分列宽: a table of three equal columns; 一键调整列宽: two edges and the arrows of a width between them.
23
+ // 均分列宽: a table of three equal columns; 自动调整列宽: two edges and the arrows of a width between them.
24
24
  even: svg('<rect x="3.25" y="4.25" width="13.5" height="11.5" rx="2"/><path d="M7.75 4.25v11.5M12.25 4.25v11.5"/>'),
25
25
  autoWidth: svg('<path d="M3.25 4v12M16.75 4v12"/><path d="M6.25 10h7.5M8.25 8l-2 2 2 2M11.75 8l2 2-2 2"/>'),
26
26
  // 合并单元格: a cell's two halves pushed together; 拆分单元格: a cell pulled apart at its middle line.
@@ -37,4 +37,6 @@ export const TABLE_ICONS = {
37
37
  // 一键优化: a magic wand and its sparks; 识别数字列: a number sign.
38
38
  magic: svg('<path d="m3.75 16.25 9-9"/><path d="m11.25 5.75 3 3"/><path d="M15.25 2.5v3M13.75 4h3M5.5 3.25v2M4.5 4.25h2M16 10.75v2M15 11.75h2"/>'),
39
39
  numbers: svg('<path d="M8.25 4 6.75 16M13.75 4l-1.5 12M4.5 8h12M3.75 12.25h12"/>'),
40
+ // 视图: three columns of cards, a board drawn from the table.
41
+ view: svg('<rect x="3.25" y="3.75" width="3.5" height="7.5" rx="1"/><rect x="8.25" y="3.75" width="3.5" height="12.5" rx="1"/><rect x="13.25" y="3.75" width="3.5" height="5" rx="1"/>'),
40
42
  };
@@ -19,12 +19,14 @@ import { MENU_WIDTH } from "../type-grid.mjs";
19
19
  import { addStyle, element } from "../ui.mjs";
20
20
  import { alignItems, alignLook } from "./aligns.mjs";
21
21
  import { clearCells, createCells } from "./cells.mjs";
22
+ import { createCellPictures } from "./pictures.mjs";
22
23
  import { TABLE_ICONS } from "./icons.mjs";
24
+ import { createViews } from "./views.mjs";
23
25
  import { createColumnWidths } from "./widths.mjs";
24
26
  import { t } from "../../../shared/i18n/index.mjs";
25
27
 
26
28
  // A table's own tools (notion-lite's simple table, src/blocks/table/; the plan's T2, its rules in
27
- // table-math-plan-2026-10-18.md), for a table written as the kit writes one (the unit the server marked GRID):
29
+ // notes/plans/table-math-plan-2026-10-18.md), for a table written as the kit writes one (the unit the server marked GRID):
28
30
  //
29
31
  // - The selection: cells (a rectangle between two of them, cells.mjs, grown so that it cuts no
30
32
  // merged cell), rows or columns, of one table; { unit, type: "cell" | "row" | "column", anchor,
@@ -54,7 +56,8 @@ import { t } from "../../../shared/i18n/index.mjs";
54
56
  // A table wider or taller than its frame scrolls in it: the tools stand by what the frame shows of
55
57
  // it (the geometry's view), the grips and + points of the rows and columns in sight.
56
58
  // Each change is one undo step; the page writes it as one operation of the table (grid.mjs). The
57
- // keys and the cells' bar are cells.mjs's.
59
+ // keys and the cells' bar are cells.mjs's; what a view of the table asks (a custom block reading it:
60
+ // set a cell, move, add or take out a row) and 视图 › of its menu, views.mjs's.
58
61
 
59
62
  const STYLE = `
60
63
  .ge-tgrip { display: flex; align-items: center; justify-content: center; cursor: grab; pointer-events: auto; }
@@ -78,7 +81,7 @@ const STYLE = `
78
81
  .ge-tplus:hover > i { width: 18px; height: 18px; background: var(--ge-accent); box-shadow: 0 0 0 2px light-dark(#ffffff, #191919); }
79
82
  .ge-tplus:hover > i > svg { display: block; }
80
83
  .ge-tline { border-radius: 1px; background: var(--ge-accent); pointer-events: none; }
81
- .ge-tgrow { box-sizing: border-box; display: grid; place-items: center; border: 1px solid var(--ge-line-strong); border-radius: 50%; background: var(--ge-bg); color: var(--ge-tx3); box-shadow: 0 1px 2px rgb(0 0 0 / 6%); cursor: nwse-resize; pointer-events: auto; transition: background 80ms, color 80ms; }
84
+ .ge-tgrow { box-sizing: border-box; display: grid; place-items: center; border: 0; border-radius: 50%; background: var(--ge-bg); color: var(--ge-tx3); box-shadow: 0 1px 3px light-dark(rgb(25 25 25 / 18%), rgb(0 0 0 / 45%)); cursor: nwse-resize; pointer-events: auto; transition: background 80ms, color 80ms; }
82
85
  .ge-tgrow:hover, .ge-tgrow[data-on] { background: light-dark(#f1f1ef, #2f2f2f); color: light-dark(#55534e, #c4c1bb); }
83
86
  .ge-tgrow > svg { width: 10px; height: 10px; fill: none; stroke: currentColor; stroke-width: 1.8; stroke-linecap: round; }
84
87
  .ge-tframe { box-sizing: border-box; border: 2px solid var(--ge-accent); border-radius: 2px; background: color-mix(in srgb, var(--ge-accent) 9%, transparent); pointer-events: none; }
@@ -105,11 +108,15 @@ const REACH = { out: 12, in: 8 }; // the pointer this near the table's top (left
105
108
  * active(): whether the tools may show. struct(parents, touched, mutate): the editor's undoable
106
109
  * structural change; look(elements, change, select): a change of classes and sizes as one undo step. selectBlock(unit):
107
110
  * select the table as a block (Esc). resizeTable(event, unit, axis): a drag of the table's width
108
- * ("x") or scroll height ("y") from an armed edge (resize/). say: the status line. ownCells(data): the
109
- * page's own text or blocks on the clipboard as rows of cells' inline HTML, or null (clipboard/).
111
+ * ("x") or scroll height ("y") from an armed edge (resize/). say: the status line. cellsOf(data): what
112
+ * the clipboard holds as rows of cells, { rows, from } (clipboard/ cellsOf), or null. upload(kind,
113
+ * body): a file sent to the report's folder (POST /__gallery/edit/upload), a picture of a cell's
114
+ * (pictures.mjs).
110
115
  * typedKey(event): a key that is the "/" or "@" menu's, standing on a cell's text (slash-menu/, at-menu/), comes before the cell's.
116
+ * recordStep(host, before): a text step of a text block, what a view's set is (history.mjs). insertBelow(unit, key,
117
+ * { attributes, done }): a block of a menu's key put in below a block in one undo step (editor.mjs), what 视图 › makes.
111
118
  */
112
- export function createTableEditing({ active, struct, look, selectBlock, resizeTable = () => false, say, ownCells = () => null, typedKey = () => false }) {
119
+ export function createTableEditing({ active, struct, look, selectBlock, resizeTable = () => false, say, cellsOf = () => null, upload = async () => { throw new Error("upload"); }, typedKey = () => false, recordStep = () => {}, insertBelow = () => {} }) {
113
120
  addStyle(STYLE);
114
121
  const menu = createMenu();
115
122
  let hover = null; // { unit, row, column, edges: { row, column } }: the cell under the pointer, and whether it is at the table's left (top) edge (edgesAt)
@@ -266,7 +273,7 @@ export function createTableEditing({ active, struct, look, selectBlock, resizeTa
266
273
  menuOpen: () => menu.isOpen,
267
274
  typedKey,
268
275
  resizeTable,
269
- ownCells,
276
+ cellsOf,
270
277
  dragging: () => drag !== null,
271
278
  keys: (on) => {
272
279
  keyboard = on;
@@ -274,6 +281,8 @@ export function createTableEditing({ active, struct, look, selectBlock, resizeTa
274
281
  },
275
282
  draw: () => draw(),
276
283
  };
284
+ const pictures = createCellPictures({ active, recordStep, say, upload });
285
+ tools.pictures = pictures;
277
286
  const cells = createCells(tools);
278
287
  const widths = createColumnWidths(tools);
279
288
 
@@ -535,7 +544,7 @@ export function createTableEditing({ active, struct, look, selectBlock, resizeTa
535
544
  if (type === "column") {
536
545
  // The columns' widths: shared out equally (several selected); the kit's own, or fixed as they are.
537
546
  if (to > from) items.push({ label: t("均分列宽"), icon: ICONS.even, run: () => widths.even(unit, from, to) });
538
- items.push({ label: t("一键调整列宽"), icon: ICONS.autoWidth, run: () => widths.fit(unit) });
547
+ items.push({ label: t("自动调整列宽"), icon: ICONS.autoWidth, run: () => widths.fit(unit) });
539
548
  }
540
549
  items.push(
541
550
  { label: t("创建副本"), icon: ICONS.duplicate, hint: "Ctrl+D", run: () => duplicate(unit, type, from, to) },
@@ -918,16 +927,27 @@ export function createTableEditing({ active, struct, look, selectBlock, resizeTa
918
927
 
919
928
  addEventListener("scroll", () => { if (!drag) draw(); }, { passive: true, capture: true });
920
929
 
921
- // The rows of a table the tools manage.
930
+ // What a view of a table asks, and 视图 › (views.mjs).
931
+ const views = createViews({ active, change, tableAt, recordStep, insertBelow, drawn: () => draw() });
932
+
933
+ // The rows of a table the tools manage. 一键优化 is a split row (menu.mjs): its words run it, its ›
934
+ // opens two of its parts to run alone, 自动调整列宽 and 识别数字列 (the user's, 2026-11-07); 视图 › last,
935
+ // where a custom block reads tables (views.mjs).
922
936
  function toolRows(unit) {
923
937
  const state = tableState(unit);
938
+ const view = views.menuRow(unit);
924
939
  return [
925
940
  { label: t("标题行"), icon: ICONS.headerRow, checked: state.headerRow, run: () => headerRow(unit, state) },
926
941
  { label: t("标题列"), icon: ICONS.headerColumn, checked: state.headerColumn, run: () => change(unit, () => setHeaderColumn(unit, !state.headerColumn), state.headerColumn ? t("已取消标题列") : t("已设为标题列")) },
927
- { label: t("一键优化"), icon: ICONS.magic, run: () => optimize(unit) },
928
- { label: t("一键调整列宽"), icon: ICONS.autoWidth, run: () => widths.fit(unit) },
942
+ {
943
+ label: t("一键优化"), icon: ICONS.magic, run: () => optimize(unit),
944
+ submenu: () => [
945
+ { label: t("自动调整列宽"), icon: ICONS.autoWidth, run: () => widths.fit(unit) },
946
+ { label: t("识别数字列"), icon: ICONS.numbers, run: () => numbers(unit) },
947
+ ],
948
+ },
929
949
  { label: t("均分列宽"), icon: ICONS.even, run: () => widths.even(unit) },
930
- { label: t("识别数字列"), icon: ICONS.numbers, run: () => numbers(unit) },
950
+ ...(view ? [view] : []),
931
951
  ];
932
952
  }
933
953
 
@@ -953,7 +973,10 @@ export function createTableEditing({ active, struct, look, selectBlock, resizeTa
953
973
  menu.close();
954
974
  clear();
955
975
  cells.update();
976
+ pictures.hide();
956
977
  },
978
+ /** The pictures of cells (pictures.mjs): files pasted into a cell, those of pasted cells made the folder's. */
979
+ pictures,
957
980
  /** The table whose cells, rows or columns are selected (no caret in one of them), or null: Ctrl+A's step to the table whole (select-all/). */
958
981
  get selectedTable() { return sel && !sel.editing && sel.unit.isConnected ? sel.unit : null; },
959
982
  /** The selection let go (blocks selected instead: select-all/). */
@@ -968,14 +991,15 @@ export function createTableEditing({ active, struct, look, selectBlock, resizeTa
968
991
  return Boolean(unit) && /^(TD|TH)$/.test(from.tagName) && /^(TD|TH)$/.test(to?.tagName ?? "") && tableAt(to) === unit;
969
992
  },
970
993
  /** The editor's UI nodes to keep in the top layer when a modal dialog opens. */
971
- get nodes() { return [...nodes, ...cells.nodes]; },
994
+ get nodes() { return [...nodes, ...cells.nodes, ...pictures.nodes]; },
972
995
  /** Whether a node is one of the tools' (a grip, an edge's strip, the corner's +, the cells' bar). */
973
- holds: (node) => Boolean(node) && [...nodes, ...cells.nodes].some((each) => each.contains(node)),
996
+ holds: (node) => Boolean(node) && [...nodes, ...cells.nodes, ...pictures.nodes].some((each) => each.contains(node)),
974
997
  /**
975
998
  * A table's rows of its block menu (notion-lite's 表格 section, under the menu's one title): a
976
999
  * table of the kind these tools manage has 标题行 and 标题列, switches (checked when on); then
977
- * actions, each applied once (no check): 一键优化, 一键调整列宽, 均分列宽, 识别数字列; any table
978
- * in its frame has its size's rows after them (layoutRows). [] for any other block.
1000
+ * actions, each applied once (no check): 一键优化 › (自动调整列宽, 识别数字列 in its submenu),
1001
+ * 均分列宽, 视图 › (where a custom block reads tables: views.mjs); any table in its frame has its
1002
+ * size's rows after them (layoutRows). [] for any other block.
979
1003
  */
980
1004
  menuItems(target) {
981
1005
  if (!target?.matches?.('[data-ge-unit-kind="table"]')) return [];