@heycys/gallery 0.1.2 → 0.2.0

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 (292) hide show
  1. package/THIRD-PARTY-NOTICES.md +2 -2
  2. package/browser/editor/components/align.mjs +58 -0
  3. package/browser/editor/components/code/index.mjs +1 -1
  4. package/browser/editor/components/embed/page.mjs +1 -1
  5. package/browser/editor/components/file/page.mjs +4 -4
  6. package/browser/editor/components/heading/index.mjs +7 -6
  7. package/browser/editor/components/icons.mjs +3 -0
  8. package/browser/editor/components/image/index.mjs +2 -0
  9. package/browser/editor/components/image/page.mjs +172 -90
  10. package/browser/editor/components/installed/index.mjs +6 -2
  11. package/browser/editor/components/installed/page.mjs +80 -13
  12. package/browser/editor/components/media/icons.mjs +13 -8
  13. package/browser/editor/components/media/page.mjs +5 -3
  14. package/browser/editor/components/media/toolbar.mjs +12 -3
  15. package/browser/editor/components/paragraph/index.mjs +4 -3
  16. package/browser/editor/components/registry.mjs +17 -5
  17. package/browser/editor/components/table/index.mjs +4 -2
  18. package/browser/editor/page/after/index.mjs +288 -0
  19. package/browser/editor/page/align.mjs +91 -0
  20. package/browser/editor/page/beside.mjs +5 -6
  21. package/browser/editor/page/block-menu/index.mjs +6 -3
  22. package/browser/editor/page/blocks.mjs +3 -1
  23. package/browser/editor/page/board/hint.mjs +64 -27
  24. package/browser/editor/page/board/index.mjs +160 -71
  25. package/browser/editor/page/board/motion.mjs +177 -0
  26. package/browser/editor/page/board/settings.mjs +4 -3
  27. package/browser/editor/page/clipboard/index.mjs +10 -3
  28. package/browser/editor/page/clipboard/own/blocks.mjs +3 -4
  29. package/browser/editor/page/clipboard/own/describe.mjs +6 -2
  30. package/browser/editor/page/commit.mjs +2 -2
  31. package/browser/editor/page/core.mjs +3 -1
  32. package/browser/editor/page/custom-page.mjs +15 -11
  33. package/browser/editor/page/editor.mjs +31 -14
  34. package/browser/editor/page/history.mjs +19 -4
  35. package/browser/editor/page/insert/index.mjs +20 -22
  36. package/browser/editor/page/menu.mjs +15 -7
  37. package/browser/editor/page/page-objects.mjs +3 -7
  38. package/browser/editor/page/present-links.mjs +5 -4
  39. package/browser/editor/page/present-shell.mjs +63 -0
  40. package/browser/editor/page/selection/index.mjs +10 -2
  41. package/browser/editor/page/table/binding.mjs +87 -0
  42. package/browser/editor/page/table/icons.mjs +0 -2
  43. package/browser/editor/page/table/index.mjs +10 -14
  44. package/browser/editor/page/table/views.mjs +5 -52
  45. package/browser/editor/page/table/widths.mjs +82 -10
  46. package/browser/editor/page/typing/index.mjs +44 -12
  47. package/browser/editor/page/typing/leave.mjs +19 -5
  48. package/browser/shared/block-packs.mjs +23 -8
  49. package/browser/shared/component-catalog.mjs +15 -8
  50. package/browser/shared/component-source.mjs +3 -1
  51. package/browser/shared/components/heading.mjs +2 -1
  52. package/browser/shared/components/installed.mjs +1 -1
  53. package/browser/shared/components/page.mjs +2 -0
  54. package/browser/shared/components/paragraph.mjs +8 -1
  55. package/browser/shared/components/table.mjs +1 -0
  56. package/browser/shared/emoji/line-icons.mjs +37 -0
  57. package/browser/shared/http.mjs +9 -0
  58. package/browser/shared/i18n/en.mjs +40 -17
  59. package/browser/shared/outline.mjs +30 -2
  60. package/browser/shared/pack-manifest.mjs +12 -1
  61. package/browser/shared/pages.mjs +169 -57
  62. package/browser/shared/pinyin.mjs +92 -0
  63. package/browser/shared/present-step.mjs +17 -0
  64. package/browser/shared/sidebar-head.mjs +70 -0
  65. package/browser/shared/web-links.mjs +5 -0
  66. package/dist/chunk-2OHANJ6Q.mjs +2 -0
  67. package/dist/{chunk-QOUEFUCH.mjs → chunk-3MBRL2PM.mjs} +1 -1
  68. package/dist/{chunk-NWR2LT5B.mjs → chunk-4OKWZY5E.mjs} +1 -1
  69. package/dist/{chunk-RMECZA2K.mjs → chunk-5K44HLTZ.mjs} +1 -1
  70. package/dist/{chunk-NFMCP2HI.mjs → chunk-5XA2ZBAE.mjs} +2 -2
  71. package/dist/{chunk-OUUP3WKT.mjs → chunk-67N2QJYT.mjs} +1 -1
  72. package/dist/chunk-6KBYRA2C.mjs +2 -0
  73. package/dist/{chunk-SX4LJYT6.mjs → chunk-6N3PX4XX.mjs} +1 -1
  74. package/dist/{chunk-RFDZXFJF.mjs → chunk-7JDX4E65.mjs} +1 -1
  75. package/dist/chunk-7M2BQQGZ.mjs +2 -0
  76. package/dist/{chunk-ZUNVAXLH.mjs → chunk-7OG26PGF.mjs} +1 -1
  77. package/dist/{chunk-B4P2CM2J.mjs → chunk-AHN3NFKJ.mjs} +1 -1
  78. package/dist/chunk-ALZ6ZENZ.mjs +3 -0
  79. package/dist/{chunk-UGWYKHBL.mjs → chunk-AR5D57ZD.mjs} +2 -2
  80. package/dist/{chunk-W3BGBJQW.mjs → chunk-BFJGHSQN.mjs} +1 -1
  81. package/dist/{chunk-HLYV7RIH.mjs → chunk-CMA72MAG.mjs} +1 -1
  82. package/dist/{chunk-D4CKRD3V.mjs → chunk-DAZL73VK.mjs} +2 -2
  83. package/dist/{chunk-6VTU6KEO.mjs → chunk-DJISHPUL.mjs} +1 -1
  84. package/dist/{chunk-BPL64HGA.mjs → chunk-EAIFITAV.mjs} +1 -1
  85. package/dist/chunk-EP25HDAJ.mjs +2 -0
  86. package/dist/{chunk-6EZ7FNIK.mjs → chunk-F4ZA6JRZ.mjs} +1 -1
  87. package/dist/{chunk-3KJHLHUO.mjs → chunk-F6HVDZR4.mjs} +1 -1
  88. package/dist/{chunk-3NJACR4W.mjs → chunk-FDMAXMQA.mjs} +1 -1
  89. package/dist/chunk-FETSREUN.mjs +5 -0
  90. package/dist/{chunk-RKPWLGZ3.mjs → chunk-GHOYKMQ3.mjs} +1 -1
  91. package/dist/chunk-HDWTZ763.mjs +12 -0
  92. package/dist/{chunk-VTKNEYT3.mjs → chunk-HPOI4ZX7.mjs} +1 -1
  93. package/dist/{chunk-OW5NWPOJ.mjs → chunk-HXG7EOPJ.mjs} +1 -1
  94. package/dist/{chunk-V6RIYQZZ.mjs → chunk-ITOH5EGO.mjs} +1 -1
  95. package/dist/{chunk-ZWPMCK7P.mjs → chunk-IV64FFI4.mjs} +1 -1
  96. package/dist/chunk-J43Z6LSS.mjs +2 -0
  97. package/dist/chunk-J5PUIV3Y.mjs +4 -0
  98. package/dist/{chunk-KTKHRC6H.mjs → chunk-JA7G53PC.mjs} +1 -1
  99. package/dist/{chunk-NWFBE2YA.mjs → chunk-JLTZF4LA.mjs} +1 -1
  100. package/dist/{chunk-GY3FAUVM.mjs → chunk-JZT7I2OJ.mjs} +1 -1
  101. package/dist/{chunk-QKXMPUXC.mjs → chunk-K5XATEOO.mjs} +1 -1
  102. package/dist/chunk-L2SUIS5S.mjs +2 -0
  103. package/dist/{chunk-TEZAWDSQ.mjs → chunk-LM4XFQHZ.mjs} +1 -1
  104. package/dist/{chunk-5ZJA7CXT.mjs → chunk-MN7BZL4R.mjs} +1 -1
  105. package/dist/chunk-MTYYHM2G.mjs +15 -0
  106. package/dist/{chunk-HMYTM3GT.mjs → chunk-MXUBKDRO.mjs} +1 -1
  107. package/dist/{chunk-MHW7ZKOU.mjs → chunk-OEXWRJME.mjs} +1 -1
  108. package/dist/{chunk-CRJEG7MT.mjs → chunk-OFHXGWOX.mjs} +1 -1
  109. package/dist/chunk-ORID3AE7.mjs +166 -0
  110. package/dist/{chunk-32ZUEFZ7.mjs → chunk-PGDE24N5.mjs} +1 -1
  111. package/dist/{chunk-UNOYVIYR.mjs → chunk-POTA2FV4.mjs} +1 -1
  112. package/dist/{chunk-N7AZZLGT.mjs → chunk-QE5RG76S.mjs} +18 -17
  113. package/dist/{chunk-N76HWBA3.mjs → chunk-R2ZDLJYT.mjs} +1 -1
  114. package/dist/chunk-SWUTTZCN.mjs +2 -0
  115. package/dist/{chunk-POQSE4C2.mjs → chunk-TR7TWGHB.mjs} +1 -1
  116. package/dist/chunk-U5XL7D6A.mjs +3 -0
  117. package/dist/{chunk-PVER7LSC.mjs → chunk-U7NZI6N4.mjs} +2 -2
  118. package/dist/{chunk-Q47PLKIJ.mjs → chunk-UGWMMEJ5.mjs} +1 -1
  119. package/dist/chunk-UJQJKNGK.mjs +2 -0
  120. package/dist/chunk-UYVCQK3H.mjs +22 -0
  121. package/dist/{chunk-FJYN7RTH.mjs → chunk-VFX2KNHP.mjs} +1 -1
  122. package/dist/{chunk-UBBRTJ2R.mjs → chunk-VS7JIGJW.mjs} +1 -1
  123. package/dist/{chunk-NVRNLK25.mjs → chunk-W7665ZEC.mjs} +2 -2
  124. package/dist/{chunk-NG375ILQ.mjs → chunk-WQDQWCX5.mjs} +1 -1
  125. package/dist/chunk-YLPSMDIS.mjs +5 -0
  126. package/dist/{chunk-VXACTLO3.mjs → chunk-YNAWBAYN.mjs} +1 -1
  127. package/dist/{chunk-ZB4H7ZN4.mjs → chunk-YROX2O22.mjs} +1 -1
  128. package/dist/{chunk-YQGT4AB2.mjs → chunk-ZDLPUOAG.mjs} +1 -1
  129. package/dist/chunk-ZQS6H473.mjs +16 -0
  130. package/dist/{chunk-OJKMINIU.mjs → chunk-ZWWC4KLF.mjs} +15 -15
  131. package/dist/cli.mjs +1 -1
  132. package/dist/server.mjs +1 -1
  133. package/dist/worker.mjs +1 -1
  134. package/kit/board.css +5 -5
  135. package/kit/code.js +15 -15
  136. package/kit/report.css +120 -41
  137. package/kit/runtime.js +45 -7
  138. package/kit/tables.js +2 -0
  139. package/kit/ui.js +2 -0
  140. package/package.json +1 -1
  141. package/packs/gallery/chart-view/kit.js +3 -3
  142. package/packs/gallery/chart-view/writing.md +1 -1
  143. package/packs/gallery/countdown/component.json +1 -1
  144. package/packs/gallery/countdown/kit.js +89 -29
  145. package/packs/gallery/countdown/preview.svg +1 -1
  146. package/packs/gallery/countdown/style.css +88 -100
  147. package/packs/gallery/countdown/writing.md +2 -2
  148. package/packs/gallery/habit/component.json +3 -3
  149. package/packs/gallery/habit/kit.js +114 -75
  150. package/packs/gallery/habit/preview.svg +1 -1
  151. package/packs/gallery/habit/style.css +133 -205
  152. package/packs/gallery/habit/writing.md +2 -2
  153. package/packs/gallery/heatmap/component.json +2 -2
  154. package/packs/gallery/heatmap/kit.js +335 -173
  155. package/packs/gallery/heatmap/preview.svg +1 -1
  156. package/packs/gallery/heatmap/style.css +158 -170
  157. package/packs/gallery/heatmap/writing.md +2 -2
  158. package/packs/gallery/kanban/kit.js +3 -3
  159. package/packs/gallery/kanban/writing.md +1 -1
  160. package/packs/gallery/metric/kit.js +3 -3
  161. package/packs/gallery/metric/writing.md +1 -1
  162. package/packs/gallery/note/component.json +3 -3
  163. package/packs/gallery/note/kit.js +40 -13
  164. package/packs/gallery/note/preview.svg +1 -1
  165. package/packs/gallery/note/style.css +51 -30
  166. package/packs/gallery/note/writing.md +2 -2
  167. package/packs/gallery/recent/component.json +2 -2
  168. package/packs/gallery/recent/kit.js +141 -86
  169. package/packs/gallery/recent/preview.svg +1 -1
  170. package/packs/gallery/recent/style.css +53 -126
  171. package/packs/gallery/recent/writing.md +2 -2
  172. package/packs/gallery/static/component.json +2 -2
  173. package/packs/gallery/static/preview.svg +1 -1
  174. package/packs/gallery/static/style.css +99 -66
  175. package/packs/gallery/static/writing.md +2 -2
  176. package/packs/gallery/stats/component.json +3 -3
  177. package/packs/gallery/stats/kit.js +253 -72
  178. package/packs/gallery/stats/preview.svg +1 -1
  179. package/packs/gallery/stats/style.css +64 -142
  180. package/packs/gallery/stats/writing.md +2 -2
  181. package/packs/gallery/today/component.json +2 -2
  182. package/packs/gallery/today/kit.js +62 -27
  183. package/packs/gallery/today/preview.svg +1 -1
  184. package/packs/gallery/today/style.css +101 -72
  185. package/packs/gallery/today/writing.md +2 -2
  186. package/packs/gallery/todos/component.json +1 -1
  187. package/packs/gallery/todos/kit.js +218 -71
  188. package/packs/gallery/todos/preview.svg +1 -1
  189. package/packs/gallery/todos/style.css +170 -223
  190. package/packs/gallery/todos/writing.md +1 -1
  191. package/packs/gallery/weather/component.json +2 -2
  192. package/packs/gallery/weather/kit.js +165 -90
  193. package/packs/gallery/weather/preview.svg +1 -1
  194. package/packs/gallery/weather/style.css +100 -218
  195. package/packs/gallery/weather/writing.md +1 -1
  196. package/packs/gallery-soft/countdown/component.json +18 -0
  197. package/packs/gallery-soft/countdown/example.html +3 -0
  198. package/packs/gallery-soft/countdown/kit.js +206 -0
  199. package/packs/gallery-soft/countdown/preview.svg +1 -0
  200. package/packs/gallery-soft/countdown/style.css +211 -0
  201. package/packs/gallery-soft/countdown/template.html +3 -0
  202. package/packs/gallery-soft/countdown/writing.md +24 -0
  203. package/packs/gallery-soft/habit/component.json +14 -0
  204. package/packs/gallery-soft/habit/example.html +3 -0
  205. package/packs/gallery-soft/habit/kit.js +366 -0
  206. package/packs/gallery-soft/habit/preview.svg +1 -0
  207. package/packs/gallery-soft/habit/style.css +251 -0
  208. package/packs/gallery-soft/habit/template.html +3 -0
  209. package/packs/gallery-soft/habit/writing.md +23 -0
  210. package/packs/gallery-soft/heatmap/component.json +18 -0
  211. package/packs/gallery-soft/heatmap/example.html +3 -0
  212. package/packs/gallery-soft/heatmap/kit.js +498 -0
  213. package/packs/gallery-soft/heatmap/preview.svg +1 -0
  214. package/packs/gallery-soft/heatmap/style.css +181 -0
  215. package/packs/gallery-soft/heatmap/template.html +3 -0
  216. package/packs/gallery-soft/heatmap/writing.md +23 -0
  217. package/packs/gallery-soft/note/component.json +14 -0
  218. package/packs/gallery-soft/note/example.html +3 -0
  219. package/packs/gallery-soft/note/kit.js +162 -0
  220. package/packs/gallery-soft/note/preview.svg +1 -0
  221. package/packs/gallery-soft/note/style.css +148 -0
  222. package/packs/gallery-soft/note/template.html +3 -0
  223. package/packs/gallery-soft/note/writing.md +20 -0
  224. package/packs/gallery-soft/recent/component.json +13 -0
  225. package/packs/gallery-soft/recent/example.html +1 -0
  226. package/packs/gallery-soft/recent/kit.js +335 -0
  227. package/packs/gallery-soft/recent/preview.svg +1 -0
  228. package/packs/gallery-soft/recent/style.css +160 -0
  229. package/packs/gallery-soft/recent/template.html +1 -0
  230. package/packs/gallery-soft/recent/writing.md +17 -0
  231. package/packs/gallery-soft/static/component.json +13 -0
  232. package/packs/gallery-soft/static/example.html +12 -0
  233. package/packs/gallery-soft/static/preview.svg +1 -0
  234. package/packs/gallery-soft/static/style.css +186 -0
  235. package/packs/gallery-soft/static/template.html +1 -0
  236. package/packs/gallery-soft/static/writing.md +20 -0
  237. package/packs/gallery-soft/stats/component.json +13 -0
  238. package/packs/gallery-soft/stats/example.html +1 -0
  239. package/packs/gallery-soft/stats/kit.js +341 -0
  240. package/packs/gallery-soft/stats/preview.svg +1 -0
  241. package/packs/gallery-soft/stats/style.css +119 -0
  242. package/packs/gallery-soft/stats/template.html +1 -0
  243. package/packs/gallery-soft/stats/writing.md +13 -0
  244. package/packs/gallery-soft/today/component.json +12 -0
  245. package/packs/gallery-soft/today/example.html +1 -0
  246. package/packs/gallery-soft/today/kit.js +222 -0
  247. package/packs/gallery-soft/today/preview.svg +1 -0
  248. package/packs/gallery-soft/today/style.css +178 -0
  249. package/packs/gallery-soft/today/template.html +1 -0
  250. package/packs/gallery-soft/today/writing.md +16 -0
  251. package/packs/gallery-soft/todos/component.json +19 -0
  252. package/packs/gallery-soft/todos/example.html +3 -0
  253. package/packs/gallery-soft/todos/kit.js +527 -0
  254. package/packs/gallery-soft/todos/preview.svg +1 -0
  255. package/packs/gallery-soft/todos/style.css +212 -0
  256. package/packs/gallery-soft/todos/template.html +3 -0
  257. package/packs/gallery-soft/todos/writing.md +32 -0
  258. package/packs/gallery-soft/weather/component.json +19 -0
  259. package/packs/gallery-soft/weather/example.html +3 -0
  260. package/packs/gallery-soft/weather/kit.js +411 -0
  261. package/packs/gallery-soft/weather/preview.svg +1 -0
  262. package/packs/gallery-soft/weather/style.css +185 -0
  263. package/packs/gallery-soft/weather/template.html +3 -0
  264. package/packs/gallery-soft/weather/writing.md +28 -0
  265. package/release.json +9 -9
  266. package/skill/SKILL.md +12 -12
  267. package/skill/references/building-blocks.md +4 -4
  268. package/skill/references/pages-and-data.md +13 -9
  269. package/skill/references/writing-html.md +2 -0
  270. package/web/assets/index-BM_K-Auu.css +1 -0
  271. package/web/assets/index-DRslOBiv.js +15 -0
  272. package/web/index.html +2 -2
  273. package/dist/chunk-2NRBY6AJ.mjs +0 -2
  274. package/dist/chunk-35NQ4PLQ.mjs +0 -2
  275. package/dist/chunk-4AV456RQ.mjs +0 -2
  276. package/dist/chunk-5XYHDBJ5.mjs +0 -2
  277. package/dist/chunk-6A53MZYZ.mjs +0 -2
  278. package/dist/chunk-6EXH3ORZ.mjs +0 -166
  279. package/dist/chunk-BVEFGE4B.mjs +0 -2
  280. package/dist/chunk-D4EURAX4.mjs +0 -4
  281. package/dist/chunk-DQCE7TJY.mjs +0 -5
  282. package/dist/chunk-FWNRPMCJ.mjs +0 -12
  283. package/dist/chunk-FWW4CSAZ.mjs +0 -2
  284. package/dist/chunk-JVHHHGEA.mjs +0 -3
  285. package/dist/chunk-PZDLJJTJ.mjs +0 -3
  286. package/dist/chunk-SXHBYZST.mjs +0 -16
  287. package/dist/chunk-UFNYFFKO.mjs +0 -20
  288. package/dist/chunk-UKSHDZZ6.mjs +0 -2
  289. package/dist/chunk-VJPFVNNW.mjs +0 -15
  290. package/dist/chunk-VS3ZMVGX.mjs +0 -5
  291. package/web/assets/index-BK2e_07w.js +0 -13
  292. package/web/assets/index-CWFI83mF.css +0 -1
@@ -1,6 +1,9 @@
1
1
  import { ARRIVING, ATTRIBUTE, DATA_MOST, DATA_SHOWN, FALLBACK, FIELDS, INSTANCE, NO_TEXT, PACKAGE_MARK, SCHEMA, SLOT, SLOT_PART, componentAt, fitsDataScript, heldBy, instanceMatch, isDataScript, noDataPart, refusedInData, schemaAhead, slotsIn } from "../../../shared/components/installed.mjs";
2
2
  import { referencedIds } from "../../../shared/copy-ids.mjs";
3
+ import { jsonIn } from "../../../shared/json-layout.mjs";
4
+ import { CHART_SOURCE, VIEW_FROM } from "../../../shared/table-chart.mjs";
3
5
  import { language, t } from "../../../shared/i18n/index.mjs";
6
+ import { searchWords } from "../../../shared/pinyin.mjs";
4
7
  import { caretAt, editable } from "../../page/caret.mjs";
5
8
  import { htmlToBlocks, parseClipboardHTML } from "../../page/clipboard/import/html.mjs";
6
9
  import { toBlocks } from "../../page/clipboard/import/to-blocks.mjs";
@@ -8,8 +11,11 @@ import { build as buildBlock } from "../../page/clipboard/own/blocks.mjs";
8
11
  import { copyOf } from "../../page/clipboard/own/describe.mjs";
9
12
  import { ownIds } from "../../page/clipboard/own/ids.mjs";
10
13
  import { firstHost, newHost, unitElement } from "../../page/core.mjs";
14
+ import { openSettings } from "../../page/board/settings.mjs";
15
+ import { bindAbove, keyOf, tableChoices } from "../../page/table/binding.mjs";
11
16
  import { addStyle } from "../../page/ui.mjs";
12
17
  import { accepts, capsFor } from "../registry.mjs";
18
+ import { SETTINGS_ICON } from "../icons.mjs";
13
19
  import { ICON } from "./index.mjs";
14
20
  import { followCatalog, followSettings, isBehind } from "./served.mjs";
15
21
 
@@ -301,9 +307,6 @@ function keepSlots(node, from, next) {
301
307
  console.error(`[DocKit] ${instance.getAttribute(ATTRIBUTE)}: a slot left its instance: it is put back, its blocks the document's`);
302
308
  }
303
309
 
304
- // A package's picture where a menu shows a mark.
305
- const pictureOf = ({ preview }) => (preview ? `<img src="${preview}" alt="">` : null);
306
-
307
310
  // A slot the file has empty (an Agent's): what a disclosure's content says (details/page.mjs), a click
308
311
  // on it making a paragraph there (insert/ clickBlank).
309
312
  const SLOT_EMPTY = `
@@ -312,7 +315,7 @@ const SLOT_EMPTY = `
312
315
  `;
313
316
 
314
317
  /** An instance on the page: what its events are, what Enter does in its words, and what the menus make of its package. */
315
- export function create({ map, newParagraph, active, sourceStep, struct }) {
318
+ export function create({ map, newParagraph, active, sourceStep, struct, look }) {
316
319
  held = map;
317
320
  addStyle(SLOT_EMPTY);
318
321
  // Whether a key in an instance, on no field of it, is undo or redo: a button or what a component draws
@@ -360,7 +363,73 @@ export function create({ map, newParagraph, active, sourceStep, struct }) {
360
363
  sourceStep(changed.map(([part, was]) => [part, was]));
361
364
  return true;
362
365
  }
366
+ // ---------- 设置 ----------
367
+ // An instance's 设置 (the handle's menu; the board's form of a custom page, page/board/settings.mjs, whose
368
+ // menu cards a choice is made in): the fields its manifest's `settings` lists, kept in its part
369
+ // `settings` (a script of JSON, what `context.editJSON` writes: one undo step, a change laid out as the
370
+ // part was), and for a view of a table (needs "tables") which table it reads, kept in its VIEW_FROM and on
371
+ // the table's frame (binding.mjs), one undo step too. Null where it has none: no field, or no part to keep
372
+ // them in, and no table to choose; an instance that does not run or that is past its manifest has no form.
373
+ const TABLE_FIELD = "__table"; // the form's field for the table: no setting of the manifest's
374
+ const settingsIn = (part) => {
375
+ try {
376
+ const value = JSON.parse(part?.textContent?.trim() || "{}");
377
+ return value && typeof value === "object" && !Array.isArray(value) ? value : {};
378
+ } catch {
379
+ return {};
380
+ }
381
+ };
382
+ function formOf(instance) {
383
+ if (!active() || instance.hasAttribute(FALLBACK) || ahead(instance)) return null;
384
+ const entry = entryOf(instance.getAttribute(ATTRIBUTE));
385
+ if (!entry) return null;
386
+ const part = dataParts(instance).find(([name]) => name === "settings")?.[1] ?? null;
387
+ const fields = part ? entry.settings ?? [] : [];
388
+ const reads = entry.needs?.includes("tables") ?? false;
389
+ return fields.length > 0 || reads ? { entry, part, fields, reads } : null;
390
+ }
391
+ // The values of the manifest's fields put in the part, one `source` step, as editJSON writes them.
392
+ function writeSettings(instance, part, values) {
393
+ write({
394
+ parts: [{ name: "settings", part }],
395
+ run({ settings: draft }) {
396
+ const text = draft.textContent ?? "";
397
+ const current = settingsIn(draft);
398
+ draft.textContent = text.trim() ? jsonIn(text, { ...current, ...values }) : JSON.stringify({ ...current, ...values });
399
+ return true;
400
+ },
401
+ }, instance);
402
+ }
403
+ // The table a view reads put on it, as one undo step: its key on both, a new one on a table with none.
404
+ function readTable(instance, frame) {
405
+ const key = frame ? keyOf(frame) : null;
406
+ const keyed = frame && frame.getAttribute(CHART_SOURCE) !== key;
407
+ look([instance, ...(keyed ? [frame] : [])], [{ attributes: { [VIEW_FROM]: key } }, ...(keyed ? [{ attributes: { [CHART_SOURCE]: key } }] : [])]);
408
+ }
409
+ function openFormOf(instance) {
410
+ const form = formOf(instance);
411
+ if (!form) return;
412
+ const choices = form.reads ? tableChoices() : [];
413
+ const bound = form.reads ? choices.findIndex(({ frame }) => frame.getAttribute(CHART_SOURCE) === instance.getAttribute(VIEW_FROM) && instance.hasAttribute(VIEW_FROM)) : -1;
414
+ const fields = [
415
+ ...(form.reads ? [{ key: TABLE_FIELD, label: t("表格"), type: "choice", choices: [["", t("(未选择)")], ...choices.map(({ label }, at) => [String(at), label])] }] : []),
416
+ ...form.fields,
417
+ ];
418
+ const box = instance.getBoundingClientRect();
419
+ const top = Math.min(Math.max(box.top, 8), innerHeight - 40);
420
+ openSettings({
421
+ fields, name: form.entry.name,
422
+ values: { ...(form.part ? settingsIn(form.part) : {}), ...(form.reads ? { [TABLE_FIELD]: bound >= 0 ? String(bound) : "" } : {}) },
423
+ anchor: { left: box.left, right: box.right, top, bottom: top + 8, width: box.width, height: 8 },
424
+ save({ [TABLE_FIELD]: table, ...values }) {
425
+ if (table !== undefined) readTable(instance, table === "" ? null : choices[Number(table)]?.frame ?? null);
426
+ if (Object.keys(values).length > 0 && form.part?.isConnected) writeSettings(instance, form.part, values);
427
+ },
428
+ });
429
+ }
363
430
  return {
431
+ /** An instance's own rows in its block menu: 设置…, where it has a form (formOf). */
432
+ menuItems: (unit) => (formOf(unit) ? [{ label: t("设置…"), icon: SETTINGS_ICON, run: () => openFormOf(unit) }] : []),
364
433
  keepsKeys: (node, event) => componentAt(node) && !editable(node) && !pageUndo(node, event),
365
434
  undoHere: (node) => componentAt(node) && !editable(node),
366
435
  keys: {
@@ -399,8 +468,8 @@ export function create({ map, newParagraph, active, sourceStep, struct }) {
399
468
  // for a divider). Its slots are boxes made on the page at once, what the template has in each made
400
469
  // blocks of the page's (an empty paragraph where it has none), so that the reader writes in one
401
470
  // before the instance is saved, and Enter in a text part goes into the slot after it. One whose needs
402
- // hold "tables" is a view a table's 视图 › offers too (`readsTables`: page/table/views.mjs), which
403
- // binds the one it makes to the table (VIEW_FROM). Where two offered have one name (the same block
471
+ // hold "tables" is a view of a table (`readsTables`), which binds itself to the nearest table above it as
472
+ // it is made (VIEW_FROM: page/table/binding.mjs). Where two offered have one name (the same block
404
473
  // of two packs: 我的待办 of Gallery 风格 and of 柔光风格), each row says its pack's name after it in grey
405
474
  // (`of`: the menu's ge-pop-of).
406
475
  menuVariants: () => {
@@ -410,8 +479,8 @@ export function create({ map, newParagraph, active, sourceStep, struct }) {
410
479
  return Object.fromEntries(offered.map((entry) => [entry.id, {
411
480
  label: entry.name[language],
412
481
  ...(counts.get(entry.name[language]) > 1 ? { of: entry.pack?.name?.[language] ?? entry.id.split("/")[0] } : {}),
413
- icon: pictureOf(entry) ?? ICON,
414
- words: `${entry.name.zh} ${entry.name.en} ${entry.id} ${entry.words}`.toLowerCase(),
482
+ icon: ICON,
483
+ words: searchWords(entry),
415
484
  sample: true,
416
485
  readsTables: entry.needs?.includes("tables") ?? false,
417
486
  preview: { src: entry.preview, says: entry.description[language] },
@@ -421,6 +490,7 @@ export function create({ map, newParagraph, active, sourceStep, struct }) {
421
490
  slotsMade(doc, instance, (slot) => blocksOfTemplate(doc, slot));
422
491
  ownIds(doc, [instance]);
423
492
  place(instance);
493
+ if (entry.needs?.includes("tables")) bindAbove(instance); // a view reads the nearest table above it; its 设置 changes that
424
494
  return editableParts(instance)[0] ?? firstHost(instance) ?? place(paragraph());
425
495
  },
426
496
  }]));
@@ -458,11 +528,8 @@ export function create({ map, newParagraph, active, sourceStep, struct }) {
458
528
  if (next) caretAt(next, "start");
459
529
  else if (next === null) selection.removeAllRanges();
460
530
  },
461
- /** Its package's picture, or the mark of any component. */
462
- iconOf: (unit) => {
463
- const entry = entryOf(unit.getAttribute(ATTRIBUTE));
464
- return (entry && pictureOf(entry)) ?? ICON;
465
- },
531
+ /** The mark of a custom block: the one every custom block has in a menu, its picture shown beside its row instead. */
532
+ iconOf: () => ICON,
466
533
  /**
467
534
  * What of an instance its component writes, part by part, as the file is to hold it (null: nothing
468
535
  * here does): its parts as the kit's dehydrate leaves them, what it and its component leave on them
@@ -1,18 +1,23 @@
1
1
  import { svg } from "../icons.mjs";
2
+ import { TABLE_ICONS } from "../../page/table/icons.mjs";
2
3
 
3
4
  // The media blocks' toolbar icons (an image's, an embed's, the block menus' rows): the editor's own line
4
5
  // drawings (components/icons.mjs svg) on the same 20 units as the menus' others, the picture in the
5
6
  // middle 16 of them. They carry no size or color: the toolbar's buttons and the menus set them.
7
+ // Plain, a few strokes each (the user, 2026-11-09: Notion's looked too close, then the bars against a
8
+ // guide line that took their place too busy): a side is the editor's own 对齐 lines, the ones a text
9
+ // block's and a table's 对齐 › show (table/icons.mjs), so one look says it everywhere; a caption a picture
10
+ // (one hill in it) over a line of words; viewing large one line corner to corner with a head at each end; three dots.
6
11
 
7
12
  export const TOOL_ICONS = {
8
- // The three sides: a picture beside the line it stands against, between a rule above and below.
9
- alignLeft: svg('<path d="M4 4.5h12M4 15.5h12"/><rect x="4" y="7.25" width="6.5" height="5.5" rx="1.25"/>'),
10
- alignCenter: svg('<path d="M4 4.5h12M4 15.5h12"/><rect x="6.75" y="7.25" width="6.5" height="5.5" rx="1.25"/>'),
11
- alignRight: svg('<path d="M4 4.5h12M4 15.5h12"/><rect x="9.5" y="7.25" width="6.5" height="5.5" rx="1.25"/>'),
12
- // A picture with two lines of caption under it.
13
- caption: svg('<rect x="4.5" y="4" width="11" height="6.5" rx="1.5"/><path d="M4.5 13.25h11M4.5 16h6"/>'),
14
- // A magnifier with a plus.
15
- expand: svg('<circle cx="9" cy="9" r="5"/><path d="m12.75 12.75 3.5 3.5M7 9h4M9 7v4"/>'),
13
+ // The three sides: the editor's alignment lines (a text block's 对齐 ›, a table's).
14
+ alignLeft: TABLE_ICONS["doc-align-left"],
15
+ alignCenter: TABLE_ICONS["doc-align-center"],
16
+ alignRight: TABLE_ICONS["doc-align-right"],
17
+ // A picture (its frame, one hill in it) over a line of words.
18
+ caption: svg('<rect x="3.75" y="3.25" width="12.5" height="9.5" rx="1.5"/><path d="m4 11.75 4-3.5 4.5 4M3.75 16.25h12.5"/>'),
19
+ // One line from corner to corner, a head at each end.
20
+ expand: svg('<path d="M11.5 4.25h4.25V8.5M8.5 15.75H4.25V11.5M15.25 4.75l-10.5 10.5"/>'),
16
21
  // An arrow down onto a line.
17
22
  download: svg('<path d="M10 4v9M6.5 9.75l3.5 3.5 3.5-3.5M4.5 16h11"/>'),
18
23
  more: svg('<circle cx="5" cy="10" r="1.3" fill="currentColor" stroke="none"/><circle cx="10" cy="10" r="1.3" fill="currentColor" stroke="none"/><circle cx="15" cy="10" r="1.3" fill="currentColor" stroke="none"/>'),
@@ -175,14 +175,16 @@ export function create({ struct, finishStep, look, say, active, blocks, newParag
175
175
  },
176
176
  /**
177
177
  * `file` pasted: a new block made by `make(doc)`, put in its place by `put` (the paste's, clipboard/:
178
- * where a block pasted there goes, one undo step; false when it could not), then `fill(figure, file)`
179
- * (its placeholder filled). Returns whether it took the file.
178
+ * where a block pasted there goes, one undo step; false when it could not), the block selected, then
179
+ * `fill(figure, file, { pasted: true })` (its placeholder filled, in the same undo step: one Ctrl+Z
180
+ * takes the paste back to what stood there). Returns whether it took the file.
180
181
  */
181
182
  paste(put, file, make, fill) {
182
183
  if (!file) return false;
183
184
  const figure = make(document);
184
185
  if (!put(figure)) return false;
185
- fill(figure, file);
186
+ blocks()?.select(figure, { quiet: true });
187
+ fill(figure, file, { pasted: true });
186
188
  return true;
187
189
  },
188
190
  };
@@ -1,3 +1,4 @@
1
+ import { IN_LAYER } from "../../../shared/layers.mjs";
1
2
  import { tooltip } from "../../page/tooltip.mjs";
2
3
  import { element } from "../../page/ui.mjs";
3
4
 
@@ -7,7 +8,7 @@ import { element } from "../../page/ui.mjs";
7
8
 
8
9
  /** The toolbar's look, and its buttons' (a popover's too: an image's 对齐 pops three of them). */
9
10
  export const TOOLBAR_STYLE = `
10
- .ge-layer > .ge-media-bar { pointer-events: auto; }
11
+ .ge-layer > .ge-media-bar { pointer-events: auto; z-index: ${IN_LAYER.button}; } /* over its block's fill while the block is selected */
11
12
  .ge-media-bar { display: flex; padding: 2px; border-radius: 6px; background: var(--ge-bg);
12
13
  box-shadow: 0 0 0 1px var(--ge-outline), 0 4px 12px -2px light-dark(rgb(25 25 25 / 8%), rgb(0 0 0 / 30%)); }
13
14
  .ge-media-tool { display: flex; align-items: center; justify-content: center; width: 24px; height: 24px; border-radius: 4px; color: var(--ge-ico2); cursor: pointer; user-select: none; transition: background 20ms ease-in; }
@@ -21,11 +22,19 @@ export const mediaBar = (label) => element("div", { class: "ge-media-bar", role:
21
22
  /**
22
23
  * A toolbar button: `label` (what it is), `tip` (the tooltip), `icon` (an svg, or a function giving
23
24
  * it, drawn by draw() each time the bar is shown), `run(button)` on a click while `alive()` (the block it stands for is
24
- * still on the page).
25
+ * still on the page). draw() puts a new icon in only when it changed: a bar placed every frame (an
26
+ * image's, while it is selected) that put its icons in anew each time took the svg a press landed on
27
+ * out of the page before the button was let go, and the browser then fired no click (2026-11-09).
25
28
  */
26
29
  export function toolButton({ label, tip, icon, run, alive }) {
27
30
  const button = element("div", { class: "ge-media-tool", role: "button", "aria-label": label });
28
- button.draw = () => { button.innerHTML = typeof icon === "function" ? icon() : icon; };
31
+ let drawn = null;
32
+ button.draw = () => {
33
+ const markup = typeof icon === "function" ? icon() : icon;
34
+ if (markup === drawn) return;
35
+ drawn = markup;
36
+ button.innerHTML = markup;
37
+ };
29
38
  if (typeof icon !== "function") button.draw(); // a function icon depends on the block: drawn when the bar is shown
30
39
  tooltip(button, tip);
31
40
  button.addEventListener("pointerdown", (event) => event.preventDefault());
@@ -1,5 +1,6 @@
1
1
  import { svg } from "../icons.mjs";
2
2
  import { PARAGRAPH, classOf } from "../kit.mjs";
3
+ import { ALIGN_TOGGLES } from "../align.mjs";
3
4
  import { t } from "../../../shared/i18n/index.mjs";
4
5
 
5
6
  // 文本 and 小字: the plain text blocks. A paragraph is the editor's default block: Enter makes one,
@@ -8,7 +9,7 @@ import { t } from "../../../shared/i18n/index.mjs";
8
9
  // default, a paragraph is the engines' own: core.mjs (newHost, splitBlock), insert/
9
10
  // (paragraphBefore, newParagraph, clickBlank), convert.mjs (typeOf tells 小字 from text), clipboard/own/
10
11
  // (a text block's description is the engine's own, and a block that says no kind is written as a paragraph).
11
- // Its color (颜色 in the block menu): class switches, colors.mjs.
12
+ // Its color (颜色 in the block menu): class switches, colors.mjs; its alignment and indent (对齐与缩进), align.mjs.
12
13
  // Its look: the kit's styles/flow.css (src/render/kit/).
13
14
  /** The class of small text's end part (the page editor's Tab), a span at the line's right end (the kit's styles/flow.css). */
14
15
  export const TAB = classOf(PARAGRAPH.tail);
@@ -23,7 +24,7 @@ export default {
23
24
  name: "paragraph",
24
25
  listed: () => t("文本"), hideable: false,
25
26
  units: {
26
- paragraph: { name: t("文本"), match: [{ rank: 180, tag: "p" }], colors: ["text", "background"], emptyIsNothing: true, fromWords: true },
27
+ paragraph: { name: t("文本"), match: [{ rank: 180, tag: "p" }], colors: ["text", "background"], toggles: ALIGN_TOGGLES, emptyIsNothing: true, fromWords: true, replacedByFile: true },
27
28
  },
28
29
  types: {
29
30
  paragraph: {
@@ -34,7 +35,7 @@ export default {
34
35
  },
35
36
  note: { // 小字: a brief label, unit or scope note
36
37
  turn: 2, menu: ["basic", 2],
37
- tag: "p", className: "doc-note", kind: "paragraph", leaf: "note", text: true, empty: true,
38
+ tag: "p", className: "doc-note", kind: "paragraph", leaf: "note", text: true, empty: true, emptyToText: true,
38
39
  corner: "paragraph", // seldom picked: the gray corner of 文本's cell (type-grid.mjs), so 文本 and the headings fill one line
39
40
  label: t("小字"), icon: svg('<path d="M6.25 8.5v-.9h7.5v.9M10 7.6v8.15M8.75 15.75h2.5"/>'), words: "小字 注释 说明 备注 标注 xiaozi zhushi shuoming beizhu xz zs sm note small caption",
40
41
  glance: { row: 11, name: "小字", write: "`<p class=\"doc-note\">`, `span.doc-tab` at its right", rule: "Kit blocks" },
@@ -44,7 +44,7 @@ import { t } from "../../shared/i18n/index.mjs";
44
44
  // without. What is hidden goes from "/", 在下方新建 and the handle's grid and nothing else
45
45
  // (page/offered.mjs); its blocks, its Markdown shortcut and "Blocks at a glance" stay.
46
46
  // units the unit kinds it defines (blocks the reader selects, moves and deletes):
47
- // { [kind]: { name, icon?, match, chapter?, fixed?, block?, handle?, below?, boxed?, beside?, inRow?, sharesHeight?, entersAfter?, resizable?, copy?, clipboard?, sizes?, toggles?, colors?, colorDefaults?, removedEmpty?, turnsEmpty?, leadsChapter?, canHaveChildren?, emptyIsNothing?, fromWords?, attributes? } }
47
+ // { [kind]: { name, icon?, match, chapter?, fixed?, block?, handle?, below?, boxed?, beside?, inRow?, sharesHeight?, entersAfter?, resizable?, copy?, clipboard?, sizes?, toggles?, colors?, colorDefaults?, removedEmpty?, turnsEmpty?, leadsChapter?, canHaveChildren?, emptyIsNothing?, fromWords?, replacedByFile?, attributes? } }
48
48
  // match: rules an element matches by its tag (one of `tag`), its class and its
49
49
  // attribute, and by the element it stands in (`parent`: { tag?, class? }, a flowchart's
50
50
  // step being an li whose parent is an ol.doc-flow), whichever are given; every
@@ -58,7 +58,7 @@ import { t } from "../../shared/i18n/index.mjs";
58
58
  // (its container's: a tab's, the Sheet area's, on the tab row); below: false, its menu
59
59
  // offers no new block below it (a tab, a Sheet area); boxed: a block with a frame of its
60
60
  // own, no text flowing beside it: a double click between two of them makes a paragraph,
61
- // a click to its right selects it, Enter on it selected puts a paragraph after it unless
61
+ // a click to its right puts the caret after it (page/after/), Enter on it selected puts a paragraph after it unless
62
62
  // it is a text block (beside.mjs), and it is a block of its own to Ctrl+A; beside: the
63
63
  // same click and Enter without being boxed (a row of columns); inRow(element): whether
64
64
  // this one stands beside another now, as a row of columns always does and a flowchart's
@@ -91,6 +91,8 @@ import { t } from "../../shared/i18n/index.mjs";
91
91
  // keys of a block stand after it as they stand in what it is in (a list: under its last item).
92
92
  // emptyIsNothing: a block of it left empty counts as nothing written, in a container
93
93
  // that says `removedEmpty`. fromWords: a block of it can be made again from its words alone.
94
+ // replacedByFile: a file pasted at the caret in an empty block of it takes the block's place (notion-lite's
95
+ // pasteFiles: an empty text block goes), else it goes after the block (page/clipboard/).
94
96
  // boxes the box kinds it defines (containers whose children are units): { [kind]: { role,
95
97
  // name?, classes?, find?, owner?, takenBy?, also?, leaveByEnter?, endIsPadding?, lead?, firstLineActs?, firstBlock?, groups?, holdsOne?, emptyIsNothing?, outer?, selectAll? } }, classes being the kit's classes that make an element one
96
98
  // (rank order, as above); the others the server knows by their tag (findUnits). find: where
@@ -165,7 +167,7 @@ import { t } from "../../shared/i18n/index.mjs";
165
167
  // types the blocks the reader can make on the page or turn a block into (the "/" menu,
166
168
  // Markdown shortcuts, the block menu), written by the server in the kit's plain markup:
167
169
  // { [type]: { tag, className?, kind, box?, leaf?, wraps?, container?, part?, text?, inside?, tex?,
168
- // empty?, resettable?, bare?, placeholder?, bar?, label?, icon?, hint?, markdown?, words?, turn?, menu?, fresh?,
170
+ // empty?, resettable?, emptyToText?, bare?, placeholder?, bar?, label?, icon?, hint?, markdown?, words?, turn?, menu?, fresh?,
169
171
  // corner?, preload?, onSplit?, create?, takesAsIs?, holder?, nests?, joins?, leadIcon?, fromSelection?, clipboard?, glance? } } and, for the blocks the page
170
172
  // and the server write apart from text, title?, content?, keyed?, written?,
171
173
  // extras?, textHost?, blanks?, blankSays? (what each says is at its component). Leaves hold
@@ -174,7 +176,8 @@ import { t } from "../../shared/i18n/index.mjs";
174
176
  // giving its markup, its words in the language t() says them in: components/placeholder.mjs
175
177
  // mediaBar); resettable: an empty block of the type
176
178
  // turns into body text on Enter, and the first of its container on Backspace at its start (a
177
- // quote's paragraph, a list item: notion-lite's `resettable`, typing/leave.mjs). leaf: the text block a block turned
179
+ // quote's paragraph, a list item: notion-lite's `resettable`, typing/leave.mjs); emptyToText: Backspace in an
180
+ // empty block of the type turns it into an empty paragraph where it stands (a heading, small text: typing/leave.mjs). leaf: the text block a block turned
178
181
  // into the type becomes; wraps: such a text block sits in a container of the type, found
179
182
  // by `container` (a selector); text: a plain text leaf; empty: a leaf written with no
180
183
  // text too (a paragraph, a heading, a list item, a code block: an empty
@@ -436,6 +439,12 @@ export const CATEGORY_NAMES = Object.fromEntries(Object.entries(CATEGORIES).map(
436
439
  */
437
440
  export const COPIED_AS_ITSELF = new Set(Object.entries(UNITS).filter(([kind, unit]) => UNIT_CATEGORY[kind] === "card" || unit.copy === "itself").map(([kind]) => kind));
438
441
 
442
+ /**
443
+ * The unit kinds drawn with no selection fill while selected alone (their own tools show it), each with
444
+ * the selector its element must hold for that (an image with its picture: a placeholder is filled).
445
+ */
446
+ export const UNFILLED_ALONE = Object.fromEntries(Object.entries(UNITS).filter(([, unit]) => unit.unfilled).map(([kind, unit]) => [kind, unit.unfilled]));
447
+
439
448
  /** What the reader calls each kind of unit (block labels while dragging, the block menu). */
440
449
  export const KIND_NAMES = Object.fromEntries(Object.entries(UNITS).filter(([, unit]) => unit.name).map(([kind, unit]) => [kind, unit.name]));
441
450
 
@@ -744,6 +753,9 @@ export const removedFromAnywhere = (kind) => UNITS[kind]?.removedEmpty === "anyw
744
753
  const NOTHING_EMPTY = flagged("emptyIsNothing");
745
754
  export const TEXT_BLOCKS = [...new Set(Object.values(BLOCK_TYPES).filter((spec) => NOTHING_EMPTY.has(spec.kind)).map((spec) => spec.tag)), ...Object.values(BOXES).filter((box) => box.emptyIsNothing).flatMap((box) => box.classes.map((rule) => `.${rule.class}`))].join(", ");
746
755
 
756
+ /** Whether an empty unit of this kind gives its place to a file pasted at its caret (`replacedByFile`). */
757
+ export const replacedByFile = (kind) => Boolean(UNITS[kind]?.replacedByFile);
758
+
747
759
  /** Whether what a unit of this kind is turned into is an empty block in its place (`turnsEmpty`). */
748
760
  export const turnsEmpty = (kind) => Boolean(UNITS[kind]?.turnsEmpty);
749
761
 
@@ -777,7 +789,7 @@ export const hasOuter = (boxKind) => BOXES[boxKind]?.outer !== false;
777
789
  /** The unit kinds with a frame of their own (`boxed`): a double click between two makes a paragraph (insert/). */
778
790
  export const BOXED = flagged("boxed");
779
791
 
780
- /** The unit kinds a click to the right of one, past the text area it stands in, selects: the boxed ones and those that say `beside` (beside.mjs). */
792
+ /** The unit kinds a click to the right of one puts the caret after (page/after/): the boxed ones and those that say `beside` (beside.mjs). */
781
793
  export const BESIDE = new Set([...BOXED, ...flagged("beside")]);
782
794
 
783
795
  /** Whether a unit of this kind stands beside another now, `element` being that unit (`beside`, `inRow`). */
@@ -1,3 +1,4 @@
1
+ import { ALIGN_PLACES } from "../align.mjs";
1
2
  import { BLOCK_COLORS } from "../colors.mjs";
2
3
  import { svg } from "../icons.mjs";
3
4
  import { SPAN } from "../../../shared/media.mjs";
@@ -53,10 +54,11 @@ export default {
53
54
  { rank: 90, class: "doc-table-wrap" },
54
55
  ],
55
56
  boxed: true,
57
+ toggles: ALIGN_PLACES, // the table placed on the page, at the left (the kit's own), centred or at the right: 对齐 ›, a text block's classes (align.mjs)
56
58
  resizable: ".doc-table-wrap[data-ge-unit]", // its right and bottom edges, once it is in the file
57
59
  copy: "itself", // within the report a copy keeps all of its markup (its scope line, its frame's size); another report's gets the table's data (tableData) made anew
58
- // 识别数字列 off, and the key a chart or a view reads it by (src/shared/table-chart.mjs), which 视图 ›
59
- // of its menu puts on a table that has none (page/table/views.mjs) in the step that puts the view in.
60
+ // 识别数字列 off, and the key a chart or a view reads it by (src/shared/table-chart.mjs), which a view
61
+ // made from a menu puts on a table that has none (page/table/binding.mjs) in the step that makes the view.
60
62
  attributes: { [NUMBERS]: (value) => value === "off", [CHART_SOURCE]: (value) => CHART_KEY.test(value) },
61
63
  sizes: {
62
64
  [SPAN]: { min: 0.15, max: 3 }, // past 1 the table is wider than the text and scrolls in its frame