@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,16 +1,17 @@
1
- import { escapeMarkup, escapeTyped } from "../../../shared/escape.mjs";
1
+ import { escapeMarkup, escapeText, escapeTyped } from "../../../shared/escape.mjs";
2
2
  import { mayBePage } from "../../../shared/page-address.mjs";
3
3
  import { OUTER, boldThroughout, boxKind, can, holdsAtoms, isEmpty, isFirstLine, isHost, keepLine, nestedLists, newTail, pastedLines, removable, removalTarget, splitBelow, UNIT, textEnd, unitElement } from "../core.mjs";
4
4
  import { formulaMaker } from "../formula/index.mjs";
5
5
  import { inlineItems, spaceAround } from "../../../shared/inline-spacing.mjs";
6
6
  import { caretAt, editable, hostOf, select } from "../caret.mjs";
7
7
  import { formatRange, joinMarks, outOfMarks, rangeAt, rangeOffsets } from "../marks.mjs";
8
- import { BASIC_UNITS, KIND_NAMES, accepts, clipboardOf, takesFormula, texOnly } from "../../components/registry.mjs";
8
+ import { BASIC_UNITS, HOSTS, KIND_NAMES, accepts, clipboardOf, takesFormula, texOnly } from "../../components/registry.mjs";
9
9
  import { listType } from "../../components/list/index.mjs";
10
10
  import { nodeAround } from "../../components/flowchart/index.mjs";
11
11
  import { cellsData } from "../../components/table/index.mjs";
12
12
  import { MIME, OLD_MIME, PASTED_SOURCE, build, checkBlocks, describe, describeAcross, formats, groupItems, holdsFormulas, joinedHtml, kindOfBlock, ownData, ownRange, parse, parseCells, parseText, plainText, prefixCopies, relinkCopies, reportOf, selectedHtml, textFormats, unmadeCopy } from "./own/index.mjs";
13
13
  import { bareAddress, externalContent, readExternal } from "./import/read.mjs";
14
+ import { parseClipboardHTML, tableRows } from "./import/html.mjs";
14
15
  import { fromMarkdown } from "./import/markdown.mjs";
15
16
  import { addressOf } from "../links/address.mjs";
16
17
  import { pageObjects, pageOf, typedAsIs } from "../page-objects.mjs";
@@ -32,7 +33,7 @@ import { t } from "../../../shared/i18n/index.mjs";
32
33
  // Ctrl+V reads the clipboard in Notion's order: the page's own blocks (or text), else another
33
34
  // program's content (import/read.mjs) as blocks, one formatted line, or plain text; picture
34
35
  // files (a screenshot) become images, unless they come with Office's or a table's HTML (Excel
35
- // puts a picture of the cells beside them).
36
+ // puts a picture of the cells beside them), right after the block, where blocks pasted there go.
36
37
  // With the caret in a text block: one line goes in at the caret, keeping the format bar's marks
37
38
  // where the block takes them, its own alone (not the caret's: notion-lite's text pasted) (text
38
39
  // copied in a block of the page with its line breaks); blocks
@@ -47,6 +48,9 @@ import { t } from "../../../shared/i18n/index.mjs";
47
48
  // block that takes links.
48
49
  // With blocks selected: the blocks go after them, in the first box out from there that takes them all;
49
50
  // and so with the caret on a formula block, which has no text to paste into.
51
+ // Into a table's cells (table/cells.mjs, what the clipboard holds as cells: cellsOf), cells go from
52
+ // the caret's cell or the selected ones; in a cell, picture files are pictures of the cell
53
+ // (单元格里的图片, table/pictures.mjs), and a table pasted anywhere keeps its cells' pictures.
50
54
  // One undo step. Images and embeds of an address are filled once on the page (one step with the paste).
51
55
 
52
56
  /**
@@ -62,8 +66,9 @@ import { t } from "../../../shared/i18n/index.mjs";
62
66
  * for words), or null. titleBold(): whether bold
63
67
  * is armed at the caret (a flowchart node's empty title: format-bar/), so that what is pasted there
64
68
  * is bold as what is typed is. showCaret(): the caret in view after text went in (caret.mjs).
69
+ * pictures(): the pictures of table cells (table/pictures.mjs: fromFiles, resolve, maker), or null.
65
70
  */
66
- export function createClipboard({ editing, blocks, struct, recordText, say, loadKatex = async () => Boolean(globalThis.katex), mention: mentionFor = null, linkPasted = () => {}, pageLink = async () => null, titleBold = () => false, showCaret = () => {} }) {
71
+ export function createClipboard({ editing, blocks, struct, recordText, say, loadKatex = async () => Boolean(globalThis.katex), mention: mentionFor = null, linkPasted = () => {}, pageLink = async () => null, titleBold = () => false, showCaret = () => {}, pictures = () => null }) {
67
72
  // ---------- copying ----------
68
73
 
69
74
  // Ctrl+C or Ctrl+X with blocks selected (and no text): the blocks go to the clipboard, and with
@@ -75,7 +80,7 @@ export function createClipboard({ editing, blocks, struct, recordText, say, load
75
80
  copyText(event, selection.getRangeAt(0));
76
81
  return;
77
82
  }
78
- const picked = editing() ? blocks().picked : [];
83
+ const picked = editing() ? blocks().folds.takenWith(blocks().picked) : []; // a folded heading with what it hides (fold/)
79
84
  if (picked.length === 0) return;
80
85
  event.preventDefault();
81
86
  // A list's item selected on its own carries its list's kind (notion-lite's item is a block of its
@@ -86,7 +91,7 @@ export function createClipboard({ editing, blocks, struct, recordText, say, load
86
91
  });
87
92
  const refused = picked.find((_, index) => !described[index]);
88
93
  if (refused) {
89
- say(refusalOf(refused), "note", 6000);
94
+ say(refusalOf(unmade(refused)), "note", 6000); // the block in it the page cannot make, as a selection across blocks says it
90
95
  return;
91
96
  }
92
97
  // A cut takes the blocks off the page, where a card's copy is of its unit: what is made only of its unit is refused, not lost.
@@ -217,10 +222,14 @@ export function createClipboard({ editing, blocks, struct, recordText, say, load
217
222
  // are (its HTML, a table of one cell, the import unwraps with a divider after it); more a table
218
223
  // of them as they were, not as another program's table comes in (made over: a header row, its
219
224
  // numbers read).
220
- const cells = parseCells(cellsData(data) || "null");
221
- if (cells?.length === 1 && cells[0].length === 1) return { kind: "rich", html: cells[0][0], own: true };
225
+ // The report they were copied from: their pictures are its files.
226
+ const copied = cellsData(data);
227
+ const cells = parseCells(copied || "null");
228
+ const from = cells ? reportIn(copied) : null;
229
+ const whence = from ? { from, same: from === reportOf(document) } : {};
230
+ if (cells?.length === 1 && cells[0].length === 1) return { kind: "rich", html: cells[0][0], own: true, ...whence };
222
231
  const table = cells ? checkBlocks([{ type: "table", rows: cells }]) : null;
223
- if (table) return { kind: "blocks", blocks: table, own: true };
232
+ if (table) return { kind: "blocks", blocks: table, own: true, ...whence };
224
233
  // Text of this page copied by the browser (a selection in a block): one line holding the page's
225
234
  // chips (a formula, a link shown with its icon, one left empty) is its text again, each chip as
226
235
  // it was (pastedLines), not what another program's HTML would make of it.
@@ -252,6 +261,14 @@ export function createClipboard({ editing, blocks, struct, recordText, say, load
252
261
  // Inline formulas pasted as the page's own (KaTeX loaded: formula/ formulaMaker).
253
262
  let formula = null;
254
263
 
264
+ // A table's cells' pictures pasted (made files of the document's folder first: table/pictures.mjs
265
+ // resolve), what a cell built of them shows (maker).
266
+ let picture = null;
267
+
268
+ // Whether what is pasted was copied in this document (`same`): the keys of tables in it are kept,
269
+ // given anew or taken off by that (own/chart-keys.mjs relinkCopies).
270
+ let here = true;
271
+
255
272
  // Images and embeds pasted with an address: filled now they are on the page.
256
273
  const fillMedia = (made) => {
257
274
  for (const figure of made.flatMap((node) => [node, ...node.querySelectorAll(`[${PASTED_SOURCE}]`)]).filter((node) => node.hasAttribute?.(PASTED_SOURCE))) {
@@ -261,13 +278,30 @@ export function createClipboard({ editing, blocks, struct, recordText, say, load
261
278
  }
262
279
  };
263
280
 
264
- // Files pasted by `at`: a block below it for the first of them the first component takes, in the
265
- // order of the page objects (`acceptsFile`, `fromFiles`: notion-lite's fileBlockDef; a picture an
266
- // image, any other file a file block). Returns whether one did.
267
- const fromFiles = (at, files) => pageObjects().some((page) => {
268
- const file = page.acceptsFile && [...files].find(page.acceptsFile);
269
- return Boolean(file) && page.fromFiles(at, [file]);
270
- });
281
+ // Files pasted by `at`: a block for the first of them the first component takes, in the order of the
282
+ // page objects (`acceptsFile`, `fromFiles`: notion-lite's fileBlockDef; a picture an image, any other
283
+ // file a file block). Where it goes is the paste's (notion-lite's pasteFiles, moveBlocks(ids, { parent:
284
+ // anchor.parent, after })): right after the block of `at` (unitElement: a new code block's code stands
285
+ // for the block), whole, where a block pasted there goes (placeFor: the first box out that takes it, a
286
+ // list or quote that does not splitting after the block), one undo step (`put`, handed to the
287
+ // component, which makes the block and fills it). Returns whether one did.
288
+ const fromFiles = (at, files) => {
289
+ const unit = unitElement(at);
290
+ if (!unit?.closest("main")) return false;
291
+ const put = (block) => {
292
+ const place = placeFor(unit, [block.getAttribute("data-ge-unit-kind")]);
293
+ if (!place) {
294
+ say(t("这里放不下这种块。"));
295
+ return false;
296
+ }
297
+ struct(place.parents, [], () => ({ touched: [], focus: null, created: placeAfter(place, [block]) }));
298
+ return true;
299
+ };
300
+ return pageObjects().some((page) => {
301
+ const file = page.acceptsFile && [...files].find(page.acceptsFile);
302
+ return Boolean(file) && page.fromFiles(put, [file]);
303
+ });
304
+ };
271
305
 
272
306
  // ---------- blocks into the page ----------
273
307
 
@@ -284,7 +318,9 @@ export function createClipboard({ editing, blocks, struct, recordText, say, load
284
318
  let stays = false;
285
319
  let box = anchor.parentElement;
286
320
  while (!takes(box)) {
287
- const outer = box?.closest(OUTER);
321
+ // A container made on the page and not written yet (a list just made of "- ", whose
322
+ // contenteditable OUTER passes over) is the block around what it holds, as the file's is.
323
+ const outer = box?.closest(`${OUTER}, [data-ge-new][data-ge-box]`);
288
324
  if (!outer?.closest("main")) return null;
289
325
  parents.push(box);
290
326
  // A list or a quote whose box does not take them splits after the anchor.
@@ -461,8 +497,8 @@ export function createClipboard({ editing, blocks, struct, recordText, say, load
461
497
  const [first, ...rest] = list;
462
498
  const joins = !replace && first.type === "paragraph" && !first.color;
463
499
  const placed = asLists(unit, joins ? rest : list);
464
- const made = placed.map((block) => build(document, block, { formula, mention }));
465
- relinkCopies(document, made); // a pasted card and its table linked to each other alone
500
+ const made = placed.map((block) => build(document, block, { formula, mention, picture }));
501
+ relinkCopies(document, made, { same: here }); // a pasted card or view and its table linked to each other alone
466
502
  prefixCopies(document, made); // a copy's drawing names its own markers
467
503
  const place = made.length ? placeAtCaret(unit, made, placed.map(kindOfBlock)) : { anchor: unit, box: unit.parentElement, parents: [unit.parentElement], splits: [] };
468
504
  if (!place) {
@@ -512,8 +548,8 @@ export function createClipboard({ editing, blocks, struct, recordText, say, load
512
548
  return;
513
549
  }
514
550
  const list = asLists(anchor, pasted);
515
- const made = list.map((block) => build(document, block, { formula, mention }));
516
- relinkCopies(document, made); // a pasted card and its table linked to each other alone
551
+ const made = list.map((block) => build(document, block, { formula, mention, picture }));
552
+ relinkCopies(document, made, { same: here }); // a pasted card or view and its table linked to each other alone
517
553
  prefixCopies(document, made); // a copy's drawing names its own markers
518
554
  const place = placeFor(anchor, list.map(kindOfBlock));
519
555
  if (!place) {
@@ -632,15 +668,22 @@ export function createClipboard({ editing, blocks, struct, recordText, say, load
632
668
  if (!data || (!host && picked.length === 0)) return;
633
669
  event.preventDefault();
634
670
  const anchor = host ?? picked.at(-1);
635
- // Picture or other files (a screenshot): an image or a file block below the block, unless they
671
+ // Picture or other files (a screenshot): an image or a file block after the block, unless they
636
672
  // come with the page's own blocks, or Office's or a table's HTML (Excel's picture of its cells).
637
673
  const files = data.files;
674
+ const selection = getSelection();
675
+ const range = host && selection.rangeCount && host.contains(selection.getRangeAt(0).startContainer) ? selection.getRangeAt(0).cloneRange() : null;
638
676
  if (files?.length > 0 && !ownData(data)) {
639
677
  const external = externalContent(data);
678
+ // In a table's cell: pictures of the cell, at the caret (单元格里的图片).
679
+ if (!external.fromOffice && !external.isTable && range && HOSTS[host.getAttribute("data-ge-kind")]?.pictures && pictures() && [...files].some((file) => /^image\//.test(file.type))) {
680
+ const at = rangeOffsets(host, range);
681
+ const made = await pictures().fromFiles(files);
682
+ if (made.length > 0 && host.isConnected) insertNodes(host, rangeAt(host, at), made, { own: true, join: false });
683
+ return;
684
+ }
640
685
  if (!external.fromOffice && !external.isTable && fromFiles(host ?? anchor, files)) return;
641
686
  }
642
- const selection = getSelection();
643
- const range = host && selection.rangeCount && host.contains(selection.getRangeAt(0).startContainer) ? selection.getRangeAt(0).cloneRange() : null;
644
687
  if (host && !range) return;
645
688
  // In code: the text with its lines.
646
689
  if (host && typedAsIs(host, (data.getData("text/plain") || "").replace(/\r\n?/g, "\n"))) return;
@@ -663,6 +706,7 @@ export function createClipboard({ editing, blocks, struct, recordText, say, load
663
706
  const formulas = content.kind === "blocks" ? holdsFormulas(content.blocks) : content.kind === "rich" && content.html.includes("doc-math-inline");
664
707
  if (formulas && (!host || takesFormula(host)) && (await loadKatex())) formula = formulaMaker();
665
708
  if (mentionFor) mention = (parts) => mentionFor(parts, Boolean(content.same), content.from);
709
+ here = content.same !== false;
666
710
  // An address alone, which HTML that reads as no text beside it does not change.
667
711
  const href = content.own && content.kind === "blocks" ? null : bareAddress(data) ?? (content.kind === "plain" ? addressOf(content.text) : null);
668
712
  const words = href ? (data.getData("text/plain") || content.text || href).trim() : ""; // read now: the clipboard's data goes with its event
@@ -670,6 +714,9 @@ export function createClipboard({ editing, blocks, struct, recordText, say, load
670
714
  // writes, by its title, so that no file holds a port. Never a web page's views.
671
715
  const page = href && mayBePage(href) && (!host || can(host, "links")) ? await pageLink(href) : null;
672
716
  if (page) content = { kind: "rich", html: `<a href="${escapeMarkup(page.href)}">${escapeMarkup(page.title)}</a>` };
717
+ // A table's cells' pictures, made files of the document's folder before the table is (one undo step with it).
718
+ const celled = content.kind === "blocks" ? pictureTexts(content.blocks) : [];
719
+ if (celled.length > 0 && pictures()) picture = pictures().maker(await pictures().resolve(celled, content.from ?? null));
673
720
  try {
674
721
  if (!host) {
675
722
  // With blocks selected: blocks after them (text as paragraphs, Markdown read).
@@ -681,7 +728,7 @@ export function createClipboard({ editing, blocks, struct, recordText, say, load
681
728
  return;
682
729
  }
683
730
  if (!host.isConnected || !host.contains(range.startContainer)) return;
684
- // An address alone: a link wherever the block takes them (a cell, a callout, a caption too).
731
+ // An address alone: a link wherever the block takes them (a cell, a caption too).
685
732
  if (href && can(host, "links")) {
686
733
  const link = document.createElement("a");
687
734
  link.setAttribute("href", page?.href ?? href);
@@ -706,7 +753,43 @@ export function createClipboard({ editing, blocks, struct, recordText, say, load
706
753
  } finally {
707
754
  formula = null;
708
755
  mention = null;
756
+ picture = null;
757
+ here = true;
758
+ }
759
+ }
760
+
761
+
762
+ /**
763
+ * The clipboard as rows of cells for a paste into a table's cells (table/cells.mjs: the caret in a
764
+ * cell, or cells selected), each cell its inline HTML: { rows, from } (`from`: the report the
765
+ * page's own was copied from, whose files its pictures are), or null when it holds nothing. In
766
+ * Notion's order (872952): the page's cells (the table tools' copy), its text or blocks (ownCells);
767
+ * another program's table, HTML that is one table and no words outside it (Excel, Google Sheets,
768
+ * Feishu, Notion, Yuque, a web page's: import/html.mjs tableRows), its cells with their marks, links,
769
+ * colors as the import maps them, line breaks and pictures, a table of one column too; a Markdown
770
+ * table (its text alone: Yuque's Markdown, a .md file's), read as a paste's Markdown with its cells'
771
+ * pictures; tab-separated lines (Excel's and Google Sheets' text), two lines or more of as many cells,
772
+ * two or more, a cell in quotes holding tabs, line breaks and "" a quote; else its text, one cell
773
+ * holding its lines.
774
+ */
775
+ function cellsOf(data) {
776
+ const copied = cellsData(data);
777
+ const cells = parseCells(copied || "null");
778
+ if (cells) return { rows: cells, from: reportIn(copied) };
779
+ const own = ownCells(data);
780
+ if (own) return { rows: own, from: origin(ownData(data)).from };
781
+ const external = externalContent(data);
782
+ const table = external.html ? tableRows(parseClipboardHTML(external.html), { colors: external.colors }) : null;
783
+ if (table?.length) return { rows: table.map((row) => row.map((cell) => richHtml(cell, { pictures: true }))), from: null };
784
+ const text = external.text.replace(/\n+$/, "");
785
+ if (/^\s*\|/m.test(text)) {
786
+ const made = toBlocks(fromMarkdown(text), null, HELD);
787
+ if (made.length === 1 && Array.isArray(made[0].rows)) return { rows: made[0].rows, from: null }; // a table alone
709
788
  }
789
+ const lines = tabbed(text);
790
+ const html = (words) => escapeText(words).replace(/\n/g, "<br>");
791
+ if (lines) return { rows: lines.map((row) => row.map(html)), from: null };
792
+ return text.trim() ? { rows: [[html(text)]], from: null } : null;
710
793
  }
711
794
 
712
795
  /**
@@ -728,7 +811,54 @@ export function createClipboard({ editing, blocks, struct, recordText, say, load
728
811
  return html ? [[html]] : null;
729
812
  }
730
813
 
731
- return { copy, copyAcross, copyBlocks, ownCells, paste, blocksAt };
814
+ return { copy, copyAcross, copyBlocks, cellsOf, paste, blocksAt };
815
+ }
816
+
817
+ // The inline HTML among described blocks (`value`, at any depth) that holds pictures: a table's cells' (单元格里的图片).
818
+ function pictureTexts(value, found = []) {
819
+ if (typeof value === "string") {
820
+ if (value.includes("<img")) found.push(value);
821
+ } else if (Array.isArray(value)) value.forEach((each) => pictureTexts(each, found));
822
+ else if (value && typeof value === "object") Object.values(value).forEach((each) => pictureTexts(each, found));
823
+ return found;
824
+ }
825
+
826
+ // The report the table tools' copy of cells says it was copied from, or null.
827
+ function reportIn(copied) {
828
+ try {
829
+ const from = JSON.parse(copied)?.report;
830
+ return typeof from === "string" ? from : null;
831
+ } catch {
832
+ return null;
833
+ }
834
+ }
835
+
836
+ /**
837
+ * Tab-separated lines as rows of cells (Excel's and Google Sheets' text, Notion's rule, 872952: two
838
+ * lines or more, each of as many cells, two or more), or null. A cell starting with a quote is in
839
+ * quotes, holding tabs and line breaks, "" a quote in it (Excel's quoting).
840
+ */
841
+ export function tabbed(text) {
842
+ if (!text.includes("\t")) return null;
843
+ const rows = [[]];
844
+ let cell = "";
845
+ let quoted = false;
846
+ for (let i = 0; i < text.length; i++) {
847
+ const character = text[i];
848
+ if (quoted) {
849
+ if (character !== '"') cell += character;
850
+ else if (text[i + 1] === '"') cell += text[++i];
851
+ else quoted = false;
852
+ } else if (character === '"' && cell === "") quoted = true;
853
+ else if (character === "\t" || character === "\n") {
854
+ rows.at(-1).push(cell);
855
+ cell = "";
856
+ if (character === "\n") rows.push([]);
857
+ } else cell += character;
858
+ }
859
+ rows.at(-1).push(cell);
860
+ const width = rows[0].length;
861
+ return rows.length > 1 && width > 1 && rows.every((row) => row.length === width) ? rows : null;
732
862
  }
733
863
 
734
864
  // What a field of plain text takes of the clipboard, as one line: the text of the page's own blocks
@@ -1,10 +1,10 @@
1
1
  import { escapeText } from "../../../../shared/escape.mjs";
2
- import { newContainer, newHost, pastedLines } from "../../core.mjs";
2
+ import { heldIn, newContainer, newHost, pastedLines } from "../../core.mjs";
3
3
  import { pageBuild } from "../../../components/builders.mjs";
4
- import { BLOCK_TYPES, COPIED_AS_ITSELF, TEXT_TYPES, TOGGLES, UNSAID, accepts, clipboardHooks, clipboardOf, isLead, sizeValue } from "../../../components/registry.mjs";
4
+ import { BLOCK_TYPES, COPIED_AS_ITSELF, HOLDS_ONE, TEXT_TYPES, TOGGLES, UNSAID, accepts, clipboardHooks, clipboardOf, isLead, sizeValue } from "../../../components/registry.mjs";
5
5
  import { BLOCK_COLORS } from "../../../components/colors.mjs";
6
6
  import { MAX_CELL_HTML } from "../../../components/table/index.mjs";
7
- import { copied, copyOf, reportOf } from "./describe.mjs";
7
+ import { copied, copyOf } from "./describe.mjs";
8
8
  import { imageSource, kindOfBlock, webPage } from "./rules.mjs";
9
9
 
10
10
  // Described blocks (describe.mjs and selection.mjs, and import/to-blocks.mjs for other programs' content) made (build),
@@ -62,7 +62,8 @@ export function checkBlocks(blocks) {
62
62
  */
63
63
  export function unmadeCopy(doc, blocks) {
64
64
  for (const block of blocks) {
65
- const found = block.type === "copy" ? ((doc && copied(doc, block)) || block.data ? null : block) : unmadeCopy(doc, heldBy(block));
65
+ // A copy made of its data is made of what that holds too (an instance's slots: a card in one).
66
+ const found = block.type === "copy" ? ((doc && copied(doc, block)) ? null : block.data ? unmadeCopy(doc, heldBy(block.data)) : block) : unmadeCopy(doc, heldBy(block));
66
67
  if (found) return found;
67
68
  }
68
69
  return null;
@@ -112,10 +113,10 @@ export function parseText(data) {
112
113
  /**
113
114
  * Inline HTML as nodes of the format bar's marks only, its lines with <br> between them; formulas
114
115
  * of other pages made the page's own by `formula(tex)` where given, links shown with their icon by
115
- * `mention(parts)` (pastedLines).
116
+ * `mention(parts)`, pictures by `picture(img)` (a table cell's: pastedLines).
116
117
  */
117
- function inline(doc, html, { formula = null, mention = null } = {}) {
118
- return pastedLines(doc, html, { formula, mention }).flatMap((line, index) => (index > 0 ? [doc.createElement("br"), ...line] : line));
118
+ function inline(doc, html, { formula = null, mention = null, picture = null } = {}) {
119
+ return pastedLines(doc, html, { formula, mention, picture }).flatMap((line, index) => (index > 0 ? [doc.createElement("br"), ...line] : line));
119
120
  }
120
121
 
121
122
 
@@ -128,7 +129,8 @@ function colored(element, block) {
128
129
  /**
129
130
  * A new block of the page from a described one (checked). `formula(tex)`: an inline formula chip of
130
131
  * the page (none: their TeX as text); `mention(parts)`: a link shown with its icon (none: a link of
131
- * its title). What each type adds is its definition's: `clipboard.build`, or the `build` of its
132
+ * its title); `picture(img)`: a table cell's picture (none: nothing; `what.inline(html, { pictures:
133
+ * true })` asks for it, a cell's text alone holding pictures). What each type adds is its definition's: `clipboard.build`, or the `build` of its
132
134
  * page.mjs (builders.mjs); a container is filled with its blocks, a text type with its inline HTML.
133
135
  */
134
136
  export function build(doc, block, options = {}) {
@@ -143,18 +145,17 @@ export function build(doc, block, options = {}) {
143
145
  copy.setAttribute("data-ge-unit-kind", block.kind);
144
146
  return copy;
145
147
  }
146
- // Elsewhere: a new one of its data (pasteBlocks checked it has some), the key a chart reads a
147
- // table by kept within the report it was copied from (chart-keys.mjs), no other report's.
148
- const data = { ...block.data };
149
- if (block.report !== reportOf(doc)) delete data.chart;
150
- return build(doc, data, options);
148
+ // Elsewhere: a new one of its data (pasteBlocks checked it has some), with the key a chart or a
149
+ // view reads a table by, which the paste then keeps, gives anew or takes off, in another document
150
+ // too (chart-keys.mjs relinkCopies: a table pasted there alone loses it, one with its reader is a pair).
151
+ return build(doc, block.data, options);
151
152
  }
152
153
  const what = {
153
154
  doc,
154
155
  block,
155
156
  host: (type = block.type) => newHost(doc, type),
156
157
  box: (type = block.type) => newContainer(doc, type),
157
- inline: (html) => inline(doc, html, options),
158
+ inline: (html, { pictures = false } = {}) => inline(doc, html, pictures ? options : { ...options, picture: null }),
158
159
  inner: (blocks) => blocks.map((each) => build(doc, each, options)),
159
160
  one: (each) => build(doc, each, options),
160
161
  colored: (element) => colored(element, block),
@@ -165,8 +166,16 @@ export function build(doc, block, options = {}) {
165
166
  };
166
167
  const made = clipboardOf(block.type).build ?? pageBuild(block.type);
167
168
  if (made) return made(what);
168
- const element = BLOCK_TYPES[block.type]?.box ? what.box() : what.host();
169
- element.append(...(BLOCK_TYPES[block.type]?.box ? what.inner(block.blocks) : what.inline(block.html)));
169
+ const { box, leaf } = BLOCK_TYPES[block.type] ?? {};
170
+ const element = box ? what.box() : what.host();
171
+ element.append(...(box ? what.inner(block.blocks) : what.inline(block.html)));
172
+ // A box that always holds a block (holdsOne: a highlight block, a callout) described with none (one
173
+ // the file has empty, copied or cut) holds an empty block of its `leaf` (a paragraph, as a new one
174
+ // made from "/" holds), after its lead (a highlight block's icon), as one a change empties does
175
+ // (core.mjs tidyEmptied) and a disclosure's content made again (details/page.mjs): a block to write
176
+ // in, and one the commit writes, where a box of no blocks is written by none (core.mjs nodeOf) and
177
+ // was gone at the next reload.
178
+ if (leaf && HOLDS_ONE.has(box) && heldIn(element).length === 0) element.append(what.host(leaf));
170
179
  return what.colored(element);
171
180
  }
172
181
 
@@ -1,53 +1,66 @@
1
- import { CHART_DATA, CHART_SOURCE, nextChartKey } from "../../../../shared/table-chart.mjs";
1
+ import { CHART_SOURCE, TABLE_READERS, nextChartKey } from "../../../../shared/table-chart.mjs";
2
2
  import { COPY_KEYS } from "../../../components/figure/index.mjs";
3
3
 
4
- // The keys of charts drawn from tables in what a paste made (docs/editor.md, "Copying blocks"): a
5
- // chart drawn from a table names the table by a key (src/shared/table-chart.mjs), and what a paste
6
- // makes of a card or a table carries its original's: a copy of it (data-ge-type="copy"), or a table
7
- // made anew of its data (components/table tableData `chart`: one cut, one whose original is gone or
8
- // changed since the copy). The rules, by key:
9
- // - a card and a table pasted together are a pair of their own: both take a new key, the first of
10
- // t1, t2 … the page does not hold, so that two pairs never cross;
11
- // - a table pasted without its card keeps its key while no table on the page carries it (a cut
12
- // table put back, one whose original was deleted: the card draws it again); otherwise it is a
13
- // table alone, its key taken off (a chart draws the first table of its key, which could be it);
14
- // - a card pasted alone keeps its key: it draws the same table as its original, both drawing it.
4
+ // The keys of tables in what a paste made (docs/editor.md, "Copying blocks"): a chart drawn from a
5
+ // table and a view of one (an instance of a custom block that reads tables) name the table by a key
6
+ // (src/shared/table-chart.mjs: TABLE_READERS, a reader), and what a paste makes of a card, a view or a
7
+ // table carries its original's: a copy of it (data-ge-type="copy"), what a clipboard carried of a view
8
+ // (its markup), or a table made anew of its data (components/table tableData `chart`: one cut, one whose
9
+ // original is gone or changed since the copy, one of another document). The rules, by key:
10
+ // - a reader and a table pasted together are a pair of their own: both take a new key, the first of
11
+ // t1, t2 … the page does not hold, so that two pairs never cross (a table copied with its board
12
+ // is a board of its own), in its document or another;
13
+ // - a table pasted without its reader keeps its key while no table on the page carries it (a cut
14
+ // table put back, one whose original was deleted: the card draws it again); otherwise, and in
15
+ // another document, it is a table alone, its key taken off (a reader reads the first table of its
16
+ // key, which could be it; another document's readers are no readers of it);
17
+ // - a reader pasted alone keeps its key in its document: it reads the same table as its original,
18
+ // both reading it; in another document it takes it off (`same` false: the clipboard's document is
19
+ // not this one), as the table it read is not there and one there carrying the key is no table of
20
+ // its (keys are t1, t2 … in every document): a view of no table, never one reading and changing that.
15
21
  // A copy's new keys ride on it (COPY_KEYS) to the server, which writes them into the copy's source
16
22
  // (core.mjs nodeOf: { copy, keys }; source/text.mjs copiedSource); a table made anew is written with
17
- // its own. The commit makes sure of both against the file as it is then (source/chart-keys.mjs) and
18
- // says what it changed (page/commit.mjs).
23
+ // its own, a view with its own or none (components/installed extras `from`). The commit makes sure of
24
+ // them against the file as it is then (source/chart-keys.mjs) and says what it changed (page/commit.mjs).
19
25
 
20
26
  // What carries a key in `root` and in what its templates hold.
27
+ const NAMES = [CHART_SOURCE, ...TABLE_READERS];
28
+ const CARRIES = NAMES.map((name) => `[${name}]`).join(", ");
21
29
  const carriers = (root) => [
22
- ...(root.matches?.(`[${CHART_DATA}], [${CHART_SOURCE}]`) ? [root] : []),
23
- ...root.querySelectorAll(`[${CHART_DATA}], [${CHART_SOURCE}]`),
30
+ ...(root.matches?.(CARRIES) ? [root] : []),
31
+ ...root.querySelectorAll(CARRIES),
24
32
  ...[...root.querySelectorAll("template")].flatMap((template) => carriers(template.content)),
25
33
  ];
26
- const keysOf = (node) => [node.getAttribute(CHART_DATA), node.getAttribute(CHART_SOURCE)].filter((key) => key !== null);
34
+ const keysOf = (node) => NAMES.map((name) => node.getAttribute(name)).filter((key) => key !== null);
35
+ const readerKey = (node) => TABLE_READERS.map((name) => node.getAttribute(name)).find((key) => key !== null) ?? null;
27
36
 
28
- /** The blocks a paste made (`made`, not on the page yet), the keys of their cards and tables made their own. */
29
- export function relinkCopies(doc, made) {
37
+ /**
38
+ * The blocks a paste made (`made`, not on the page yet), the keys of their cards, views and tables made
39
+ * their own; `same`: the clipboard's document is this one (clipboard/index.mjs origin).
40
+ */
41
+ export function relinkCopies(doc, made, { same = true } = {}) {
30
42
  const inMade = made.flatMap(carriers);
31
- const hosts = inMade.filter((node) => node.hasAttribute(CHART_DATA));
43
+ const hosts = inMade.filter((node) => readerKey(node) !== null);
32
44
  const frames = inMade.filter((node) => node.hasAttribute(CHART_SOURCE));
33
- if (frames.length === 0) return;
45
+ if (frames.length === 0 && (same || hosts.length === 0)) return;
34
46
  const onPage = carriers(doc);
35
47
  const taken = new Set([...onPage, ...inMade].flatMap(keysOf));
36
- const renamed = new Map(); // a key -> its new value, null: taken off a table
37
- for (const key of new Set(frames.map((frame) => frame.getAttribute(CHART_SOURCE)))) {
38
- if (hosts.some((host) => host.getAttribute(CHART_DATA) === key)) {
48
+ const renamed = new Map(); // a key -> its new value, null: taken off
49
+ const tabled = new Set(frames.map((frame) => frame.getAttribute(CHART_SOURCE)));
50
+ for (const key of tabled) {
51
+ if (hosts.some((host) => readerKey(host) === key)) {
39
52
  const next = nextChartKey(taken);
40
53
  taken.add(next);
41
54
  renamed.set(key, next);
42
- } else if (onPage.some((node) => node.getAttribute(CHART_SOURCE) === key)) renamed.set(key, null);
55
+ } else if (!same || onPage.some((node) => node.getAttribute(CHART_SOURCE) === key)) renamed.set(key, null);
43
56
  }
57
+ if (!same) for (const host of hosts) if (!tabled.has(readerKey(host))) renamed.set(readerKey(host), null);
44
58
  const sent = new Map(); // a copy -> its keys { old: new | null }
45
- for (const [name, nodes] of [[CHART_DATA, hosts], [CHART_SOURCE, frames]]) {
59
+ for (const [name, nodes] of [...TABLE_READERS.map((reader) => [reader, hosts]), [CHART_SOURCE, frames]]) {
46
60
  for (const node of nodes) {
47
61
  const key = node.getAttribute(name);
48
- if (!renamed.has(key)) continue;
62
+ if (key === null || !renamed.has(key)) continue;
49
63
  const next = renamed.get(key);
50
- if (next === null && name === CHART_DATA) continue; // a card keeps the key of a table pasted alone
51
64
  if (next === null) node.removeAttribute(name);
52
65
  else node.setAttribute(name, next);
53
66
  const copy = node.closest('[data-ge-type="copy"]');
@@ -2,7 +2,7 @@ import { isHost, nestedBlocks, serializeInner, unitsOf } from "../../core.mjs";
2
2
  import { BLOCK_TYPES, COPIED_AS_ITSELF, COPY_KEEPS, TEXT_TYPES, askClipboard, clipboardOf, sizeValue, unitClipboard } from "../../../components/registry.mjs";
3
3
  import { BLOCK_COLORS } from "../../../components/colors.mjs";
4
4
  import { containerType, typeOf } from "../../convert.mjs";
5
- import { pageOfType } from "../../page-objects.mjs";
5
+ import { pageOfType, pageOfUnit } from "../../page-objects.mjs";
6
6
  import { referencedIds } from "../../../../shared/copy-ids.mjs";
7
7
 
8
8
  // Selected blocks as the clipboard's own description (docs/editor.md, "Copying blocks"): each
@@ -64,6 +64,10 @@ export function copied(doc, block) {
64
64
  if (block.report !== reportOf(doc)) return null;
65
65
  const unit = doc.querySelector(`main [data-ge-unit="${block.unit}"]`);
66
66
  if (!unit || unit.getAttribute("data-ge-unit-kind") !== block.kind) return null;
67
+ // One whose unit's copy cannot stand for it (`copiesAsItself`: an instance with slots) is made of
68
+ // what it carries, here too: that copy would hold blocks the file writes whole, with ids no answer
69
+ // of a commit gives the page (source/apply.mjs restoredText names the block alone).
70
+ if (pageOfUnit(unit)?.copiesAsItself?.(unit) === false) return null;
67
71
  const copy = copyOf(unit);
68
72
  return (typeof block.data?.html === "string" ? copy.outerHTML === block.html : copy.textContent === block.text) ? unit : null;
69
73
  }
@@ -84,12 +88,6 @@ const plain = (node) => (node?.textContent ?? "").replace(/\s+/g, " ").trim();
84
88
  /** What copies of a block the page could make: { type, html, text, blocks, lists }, or null. */
85
89
  export function describe(node) {
86
90
  const kind = node.getAttribute("data-ge-unit-kind");
87
- if (COPIES.has(kind)) {
88
- if (!node.hasAttribute("data-ge-unit") || node.hasAttribute("data-ge-new")) return null; // not in the file yet
89
- const copy = copyOf(node);
90
- const data = unitClipboard(node).data?.(node, { serializeInner, copyOf, clipboardOf, copiedType, page: pageOfType });
91
- return { type: "copy", kind, unit: Number(node.getAttribute("data-ge-unit")), report: reportOf(node.ownerDocument), text: copy.textContent, html: copy.outerHTML, ...(data ? { data } : {}) };
92
- }
93
91
  // What an element holds: its units. One that is no box has none (a list of a class of its own:
94
92
  // source/units.mjs boxKind), and what stands in it is read as it stands.
95
93
  const holding = (box) => {
@@ -98,6 +96,17 @@ export function describe(node) {
98
96
  const blocks = (units.length > 0 || box.hasAttribute("data-ge-box") ? units : [...box.children]).map(describe);
99
97
  return blocks.every(Boolean) ? blocks : null;
100
98
  };
99
+ // Copied as itself. One whose unit's copy cannot stand for it (`copiesAsItself` of its page object:
100
+ // an instance with slots, whose blocks that copy would write whole) is copied by what it carries
101
+ // alone (`data`, those blocks described apart), and is no copy where it carries nothing (a block in a
102
+ // slot the page cannot make).
103
+ if (COPIES.has(kind)) {
104
+ if (!node.hasAttribute("data-ge-unit") || node.hasAttribute("data-ge-new")) return null; // not in the file yet
105
+ const copy = copyOf(node);
106
+ const data = unitClipboard(node).data?.(node, { serializeInner, copyOf, clipboardOf, copiedType, page: pageOfType, holding });
107
+ if (!data && pageOfUnit(node)?.copiesAsItself?.(node) === false) return null;
108
+ return { type: "copy", kind, unit: Number(node.getAttribute("data-ge-unit")), report: reportOf(node.ownerDocument), text: copy.textContent, html: copy.outerHTML, ...(data ? { data } : {}) };
109
+ }
101
110
  const what = { page: pageOfType, holding, describe, copiedType, isHost, nestedBlocks, serializeInner, plain, colorOf, sizeValue };
102
111
  const block = askClipboard("describe", node, what);
103
112
  if (block !== undefined) return block;
@@ -10,16 +10,16 @@ import { WRITERS, heldToWords } from "./writers.mjs";
10
10
  // Copied blocks for other programs (notion-lite serialize.js, after Notion 210528 / 389867: the
11
11
  // Markdown its export writes, and HTML that reads as the same), each block by the writer of its kind
12
12
  // (writers.mjs). Pasted back here without the clipboard's own data, both read as the same blocks
13
- // (import/), but for a callout: its Markdown a highlight block, its HTML a paragraph.
13
+ // (import/), but for a callout: its Markdown a highlight block, its HTML a group of its blocks.
14
14
  // text/plain Markdown: # … #### headings, "- " / "1. " / "- [ ] " items (an item's lists 4 spaces
15
- // in), "> " quotes, <aside> callouts (a highlight block: its emoji and text, its blocks;
16
- // a callout: its text),
15
+ // in), "> " quotes, <aside> callouts (a highlight block and a callout: its emoji, a highlight
16
+ // block's, and the text of its first block, its other blocks),
17
17
  // ``` code (its language), $$ formula blocks (an empty one: none), | tables |, ---, a disclosure as an item
18
18
  // holding its blocks, a tabs area as each tab's name and blocks (a row of columns, copied
19
19
  // as itself, as its text); **bold** *italic* ~~strike~~ `code` $formula$, links as their text
20
20
  // (Notion's plain text); a list's items one line apart, other blocks an empty line; a
21
21
  // line that would read as a tag or a fence escaped (writers.mjs heldToWords).
22
- // text/html plain markup: p (a callout's too), h1–h4, ul / ol / li ("[x] " / "[ ] " before a to-do's text), blockquote,
22
+ // text/html plain markup: p, a div of a highlight block's or a callout's blocks, h1–h4, ul / ol / li ("[x] " / "[ ] " before a to-do's text), blockquote,
23
23
  // details, pre > code.language-x, hr, table, a formula block as $$ … $$ (an empty one:
24
24
  // nothing, as in Markdown) and an inline one
25
25
  // as $ … $ (Notion's export), colors as the kit's classes with their color in a style.
@@ -27,8 +27,8 @@ import { WRITERS, heldToWords } from "./writers.mjs";
27
27
  // both. Text selected in one block (textFormats) is its inline HTML for other programs, and as plain
28
28
  // text its words alone (notion-lite's inlinePlain: no list's marker, no Markdown).
29
29
 
30
- // The kit's light colors, for programs without its styles (src/shared/colors.mjs).
31
- const INK = Object.fromEntries(COLORS.flatMap(({ name, text, fill }) => [[`doc-text-${name}`, `color:${text[0]}`], [`doc-highlight-${name}`, `background-color:${fill[0]}`]]));
30
+ // The kit's light colors (a background on words its words' fill), for programs without its styles (src/shared/colors.mjs).
31
+ const INK = Object.fromEntries(COLORS.flatMap(({ name, text, mark }) => [[`doc-text-${name}`, `color:${text[0]}`], [`doc-highlight-${name}`, `background-color:${mark[0]}`]]));
32
32
  const FORMULA = /^\s*\\\(([\s\S]*)\\\)\s*$/;
33
33
 
34
34
  // Inline HTML (the format bar's marks: serializeInner's) as nodes to walk, a link shown with its icon