@heycys/gallery 0.0.0-stage → 0.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +50 -2
- package/THIRD-PARTY-NOTICES.md +3303 -0
- package/assets/writing-preferences.md +107 -0
- package/bin/gallery.mjs +10 -0
- package/browser/editor/components/bookmark/icons.mjs +6 -0
- package/browser/editor/components/bookmark/index.mjs +80 -0
- package/browser/editor/components/bookmark/page.mjs +147 -0
- package/browser/editor/components/builders.mjs +19 -0
- package/browser/editor/components/callout/index.mjs +64 -0
- package/browser/editor/components/code/index.mjs +327 -0
- package/browser/editor/components/code/page.mjs +561 -0
- package/browser/editor/components/colors.mjs +50 -0
- package/browser/editor/components/columns/index.mjs +104 -0
- package/browser/editor/components/columns/page.mjs +310 -0
- package/browser/editor/components/details/index.mjs +73 -0
- package/browser/editor/components/details/page.mjs +86 -0
- package/browser/editor/components/dialog/index.mjs +84 -0
- package/browser/editor/components/dialog/page.mjs +201 -0
- package/browser/editor/components/divider/index.mjs +48 -0
- package/browser/editor/components/embed/icons.mjs +11 -0
- package/browser/editor/components/embed/index.mjs +123 -0
- package/browser/editor/components/embed/page.mjs +309 -0
- package/browser/editor/components/figure/index.mjs +87 -0
- package/browser/editor/components/figure/page.mjs +42 -0
- package/browser/editor/components/file/icons.mjs +14 -0
- package/browser/editor/components/file/index.mjs +77 -0
- package/browser/editor/components/file/page.mjs +114 -0
- package/browser/editor/components/flowchart/add.mjs +123 -0
- package/browser/editor/components/flowchart/index.mjs +246 -0
- package/browser/editor/components/flowchart/page.mjs +453 -0
- package/browser/editor/components/heading/index.mjs +53 -0
- package/browser/editor/components/heading/page.mjs +6 -0
- package/browser/editor/components/highlight/index.mjs +63 -0
- package/browser/editor/components/icon/index.mjs +57 -0
- package/browser/editor/components/icon/page.mjs +286 -0
- package/browser/editor/components/icons.mjs +48 -0
- package/browser/editor/components/image/crop.mjs +189 -0
- package/browser/editor/components/image/index.mjs +104 -0
- package/browser/editor/components/image/page.mjs +385 -0
- package/browser/editor/components/image/viewer.mjs +213 -0
- package/browser/editor/components/installed/index.mjs +179 -0
- package/browser/editor/components/installed/page.mjs +523 -0
- package/browser/editor/components/installed/served.mjs +35 -0
- package/browser/editor/components/kit.mjs +67 -0
- package/browser/editor/components/list/index.mjs +194 -0
- package/browser/editor/components/list/join.mjs +68 -0
- package/browser/editor/components/list/numbers.mjs +107 -0
- package/browser/editor/components/list/page.mjs +632 -0
- package/browser/editor/components/math/index.mjs +88 -0
- package/browser/editor/components/math/page.mjs +236 -0
- package/browser/editor/components/math/tex-logo.mjs +6 -0
- package/browser/editor/components/media/icons.mjs +19 -0
- package/browser/editor/components/media/page.mjs +192 -0
- package/browser/editor/components/media/parts.mjs +60 -0
- package/browser/editor/components/media/size.mjs +20 -0
- package/browser/editor/components/media/toolbar.mjs +37 -0
- package/browser/editor/components/media/write.mjs +7 -0
- package/browser/editor/components/pages.mjs +46 -0
- package/browser/editor/components/paragraph/index.mjs +43 -0
- package/browser/editor/components/paragraph/page.mjs +52 -0
- package/browser/editor/components/placeholder-bar.mjs +17 -0
- package/browser/editor/components/placeholder.mjs +128 -0
- package/browser/editor/components/quote/index.mjs +33 -0
- package/browser/editor/components/registry.mjs +859 -0
- package/browser/editor/components/rows.mjs +16 -0
- package/browser/editor/components/section/index.mjs +42 -0
- package/browser/editor/components/section/page.mjs +141 -0
- package/browser/editor/components/set-apart.mjs +24 -0
- package/browser/editor/components/sheets/index.mjs +137 -0
- package/browser/editor/components/sheets/page.mjs +227 -0
- package/browser/editor/components/sheets/pills.mjs +226 -0
- package/browser/editor/components/table/grid.mjs +73 -0
- package/browser/editor/components/table/index.mjs +308 -0
- package/browser/editor/components/table/page.mjs +683 -0
- package/browser/editor/components/table/slots.mjs +41 -0
- package/browser/editor/components/widget/index.mjs +50 -0
- package/browser/editor/page/annotate/anchors.mjs +230 -0
- package/browser/editor/page/annotate/card.mjs +102 -0
- package/browser/editor/page/annotate/index.mjs +1656 -0
- package/browser/editor/page/at-menu/index.mjs +317 -0
- package/browser/editor/page/autosave.mjs +1023 -0
- package/browser/editor/page/beside.mjs +21 -0
- package/browser/editor/page/block-info.mjs +63 -0
- package/browser/editor/page/block-menu/colors.mjs +84 -0
- package/browser/editor/page/block-menu/index.mjs +217 -0
- package/browser/editor/page/blocks.mjs +255 -0
- package/browser/editor/page/caret.mjs +682 -0
- package/browser/editor/page/changes/bar.mjs +102 -0
- package/browser/editor/page/changes/ghost.mjs +206 -0
- package/browser/editor/page/changes/gone-words.mjs +94 -0
- package/browser/editor/page/changes/index.mjs +447 -0
- package/browser/editor/page/changes/words.mjs +27 -0
- package/browser/editor/page/chip-fills.mjs +126 -0
- package/browser/editor/page/clipboard/import/colors.mjs +192 -0
- package/browser/editor/page/clipboard/import/html.mjs +792 -0
- package/browser/editor/page/clipboard/import/inline.mjs +232 -0
- package/browser/editor/page/clipboard/import/languages.mjs +42 -0
- package/browser/editor/page/clipboard/import/markdown.mjs +760 -0
- package/browser/editor/page/clipboard/import/math.mjs +100 -0
- package/browser/editor/page/clipboard/import/office.mjs +245 -0
- package/browser/editor/page/clipboard/import/read.mjs +120 -0
- package/browser/editor/page/clipboard/import/rich.mjs +29 -0
- package/browser/editor/page/clipboard/import/to-blocks.mjs +290 -0
- package/browser/editor/page/clipboard/index.mjs +816 -0
- package/browser/editor/page/clipboard/own/blocks.mjs +211 -0
- package/browser/editor/page/clipboard/own/chart-keys.mjs +58 -0
- package/browser/editor/page/clipboard/own/describe.mjs +124 -0
- package/browser/editor/page/clipboard/own/export.mjs +167 -0
- package/browser/editor/page/clipboard/own/ids.mjs +39 -0
- package/browser/editor/page/clipboard/own/index.mjs +13 -0
- package/browser/editor/page/clipboard/own/rules.mjs +44 -0
- package/browser/editor/page/clipboard/own/selection.mjs +159 -0
- package/browser/editor/page/clipboard/own/writers.mjs +315 -0
- package/browser/editor/page/columns/index.mjs +360 -0
- package/browser/editor/page/commit.mjs +1813 -0
- package/browser/editor/page/conflicts.mjs +249 -0
- package/browser/editor/page/convert.mjs +831 -0
- package/browser/editor/page/core.mjs +1693 -0
- package/browser/editor/page/drag/drop.mjs +307 -0
- package/browser/editor/page/drag/index.mjs +351 -0
- package/browser/editor/page/drag/preview.mjs +126 -0
- package/browser/editor/page/edge-scroll.mjs +50 -0
- package/browser/editor/page/editor.mjs +1780 -0
- package/browser/editor/page/emoji-picker/emoji-tab.mjs +287 -0
- package/browser/editor/page/emoji-picker/glyph-html.mjs +26 -0
- package/browser/editor/page/emoji-picker/grid.mjs +81 -0
- package/browser/editor/page/emoji-picker/icon-tab.mjs +217 -0
- package/browser/editor/page/emoji-picker/icons.mjs +31 -0
- package/browser/editor/page/emoji-picker/index.mjs +166 -0
- package/browser/editor/page/emoji-picker/styles.mjs +161 -0
- package/browser/editor/page/emoji-picker/support.mjs +204 -0
- package/browser/editor/page/emoji-picker/upload.mjs +236 -0
- package/browser/editor/page/export-report.mjs +23 -0
- package/browser/editor/page/fills.mjs +62 -0
- package/browser/editor/page/find/index.mjs +107 -0
- package/browser/editor/page/flags.mjs +70 -0
- package/browser/editor/page/fold/index.mjs +348 -0
- package/browser/editor/page/fold/rule.mjs +125 -0
- package/browser/editor/page/folded.mjs +23 -0
- package/browser/editor/page/format-bar/bar.mjs +449 -0
- package/browser/editor/page/format-bar/brush.mjs +77 -0
- package/browser/editor/page/format-bar/colors.mjs +46 -0
- package/browser/editor/page/format-bar/index.mjs +404 -0
- package/browser/editor/page/formula/index.mjs +236 -0
- package/browser/editor/page/formula/panel.mjs +336 -0
- package/browser/editor/page/formula/symbols.mjs +156 -0
- package/browser/editor/page/frame.mjs +74 -0
- package/browser/editor/page/frames.mjs +196 -0
- package/browser/editor/page/geometry.mjs +402 -0
- package/browser/editor/page/gesture.mjs +45 -0
- package/browser/editor/page/handle/index.mjs +650 -0
- package/browser/editor/page/handle-sizes.mjs +14 -0
- package/browser/editor/page/hints/index.mjs +84 -0
- package/browser/editor/page/history.mjs +401 -0
- package/browser/editor/page/insert/index.mjs +256 -0
- package/browser/editor/page/kept.mjs +38 -0
- package/browser/editor/page/links/address.mjs +40 -0
- package/browser/editor/page/links/index.mjs +866 -0
- package/browser/editor/page/links/pages.mjs +131 -0
- package/browser/editor/page/links/views.mjs +369 -0
- package/browser/editor/page/long-runs.mjs +75 -0
- package/browser/editor/page/look.mjs +77 -0
- package/browser/editor/page/made.mjs +24 -0
- package/browser/editor/page/margin.mjs +373 -0
- package/browser/editor/page/markdown/index.mjs +88 -0
- package/browser/editor/page/markdown/rules.mjs +33 -0
- package/browser/editor/page/marks.mjs +377 -0
- package/browser/editor/page/media-menu/index.mjs +158 -0
- package/browser/editor/page/menu.mjs +544 -0
- package/browser/editor/page/merge.mjs +124 -0
- package/browser/editor/page/notices.mjs +142 -0
- package/browser/editor/page/offered.mjs +32 -0
- package/browser/editor/page/outline/folds.mjs +53 -0
- package/browser/editor/page/outline/index.mjs +783 -0
- package/browser/editor/page/outline/list.mjs +184 -0
- package/browser/editor/page/outline/read.mjs +201 -0
- package/browser/editor/page/outline/strip.mjs +287 -0
- package/browser/editor/page/outline/tree.mjs +248 -0
- package/browser/editor/page/overlay-layer.mjs +227 -0
- package/browser/editor/page/overlays.mjs +205 -0
- package/browser/editor/page/own.mjs +28 -0
- package/browser/editor/page/pads.mjs +71 -0
- package/browser/editor/page/page-objects.mjs +105 -0
- package/browser/editor/page/panel.mjs +65 -0
- package/browser/editor/page/placement.mjs +58 -0
- package/browser/editor/page/post.mjs +41 -0
- package/browser/editor/page/present-links.mjs +50 -0
- package/browser/editor/page/quiet.mjs +48 -0
- package/browser/editor/page/resize/index.mjs +327 -0
- package/browser/editor/page/select-all/index.mjs +262 -0
- package/browser/editor/page/selection/delete.mjs +61 -0
- package/browser/editor/page/selection/index.mjs +164 -0
- package/browser/editor/page/selection/marquee.mjs +174 -0
- package/browser/editor/page/session.mjs +168 -0
- package/browser/editor/page/slash-menu/index.mjs +291 -0
- package/browser/editor/page/storage.mjs +48 -0
- package/browser/editor/page/sync-state.mjs +267 -0
- package/browser/editor/page/table/aligns.mjs +29 -0
- package/browser/editor/page/table/cell-bar.mjs +141 -0
- package/browser/editor/page/table/cells.mjs +527 -0
- package/browser/editor/page/table/icons.mjs +40 -0
- package/browser/editor/page/table/index.mjs +990 -0
- package/browser/editor/page/table/lists.mjs +187 -0
- package/browser/editor/page/table/widths.mjs +313 -0
- package/browser/editor/page/tex.mjs +32 -0
- package/browser/editor/page/text-select/index.mjs +671 -0
- package/browser/editor/page/tooltip.mjs +98 -0
- package/browser/editor/page/type-grid.mjs +83 -0
- package/browser/editor/page/typing/code-edges.mjs +274 -0
- package/browser/editor/page/typing/index.mjs +282 -0
- package/browser/editor/page/typing/leave.mjs +68 -0
- package/browser/editor/page/ui.mjs +160 -0
- package/browser/shared/annotations.mjs +569 -0
- package/browser/shared/code-folds.mjs +14 -0
- package/browser/shared/code-languages.mjs +70 -0
- package/browser/shared/code-lines.mjs +30 -0
- package/browser/shared/colors.mjs +30 -0
- package/browser/shared/component-catalog.mjs +573 -0
- package/browser/shared/components/bookmark.mjs +26 -0
- package/browser/shared/components/callout.mjs +9 -0
- package/browser/shared/components/chart.mjs +20 -0
- package/browser/shared/components/code.mjs +37 -0
- package/browser/shared/components/columns.mjs +16 -0
- package/browser/shared/components/details.mjs +15 -0
- package/browser/shared/components/dialog.mjs +28 -0
- package/browser/shared/components/diff.mjs +18 -0
- package/browser/shared/components/divider.mjs +6 -0
- package/browser/shared/components/embed.mjs +25 -0
- package/browser/shared/components/figure.mjs +14 -0
- package/browser/shared/components/file.mjs +23 -0
- package/browser/shared/components/heading.mjs +6 -0
- package/browser/shared/components/highlight.mjs +9 -0
- package/browser/shared/components/icon.mjs +18 -0
- package/browser/shared/components/image.mjs +39 -0
- package/browser/shared/components/index.mjs +396 -0
- package/browser/shared/components/installed.mjs +232 -0
- package/browser/shared/components/list.mjs +146 -0
- package/browser/shared/components/math.mjs +49 -0
- package/browser/shared/components/mention.mjs +33 -0
- package/browser/shared/components/page.mjs +46 -0
- package/browser/shared/components/paragraph.mjs +9 -0
- package/browser/shared/components/quote.mjs +6 -0
- package/browser/shared/components/section.mjs +8 -0
- package/browser/shared/components/sheets.mjs +80 -0
- package/browser/shared/components/state.mjs +20 -0
- package/browser/shared/components/table.mjs +49 -0
- package/browser/shared/components/text.mjs +14 -0
- package/browser/shared/components/widget.mjs +10 -0
- package/browser/shared/copy-ids.mjs +72 -0
- package/browser/shared/css-references.mjs +110 -0
- package/browser/shared/document-look.mjs +178 -0
- package/browser/shared/emoji/custom.mjs +91 -0
- package/browser/shared/emoji/data/LICENSE-lucide.txt +43 -0
- package/browser/shared/emoji/data/LICENSE-mingcute.txt +202 -0
- package/browser/shared/emoji/data/LICENSE-tabler.txt +21 -0
- package/browser/shared/emoji/data/README.md +28 -0
- package/browser/shared/emoji/data/categories.json +1 -0
- package/browser/shared/emoji/data/icons.json +1 -0
- package/browser/shared/emoji/data/keywords-en.json +1 -0
- package/browser/shared/emoji/data/keywords-zh.json +1 -0
- package/browser/shared/emoji/data/names.json +1 -0
- package/browser/shared/emoji/data/positions.json +1 -0
- package/browser/shared/emoji/data/twemoji-index.json +1 -0
- package/browser/shared/emoji/data/twemoji-svg.bin +0 -0
- package/browser/shared/emoji/data.mjs +194 -0
- package/browser/shared/emoji/emoji.mjs +38 -0
- package/browser/shared/emoji/glyphs.mjs +134 -0
- package/browser/shared/emoji/icon-value.mjs +91 -0
- package/browser/shared/escape.mjs +20 -0
- package/browser/shared/export-wrap.mjs +89 -0
- package/browser/shared/files.mjs +33 -0
- package/browser/shared/html-tree.mjs +59 -0
- package/browser/shared/http.mjs +22 -0
- package/browser/shared/i18n/en.mjs +1223 -0
- package/browser/shared/i18n/index.mjs +132 -0
- package/browser/shared/ids.mjs +24 -0
- package/browser/shared/import-types.mjs +23 -0
- package/browser/shared/inline-spacing.mjs +97 -0
- package/browser/shared/layers.mjs +42 -0
- package/browser/shared/long-runs.mjs +39 -0
- package/browser/shared/media.mjs +162 -0
- package/browser/shared/new-names.mjs +67 -0
- package/browser/shared/number-reading.mjs +92 -0
- package/browser/shared/old-names.mjs +143 -0
- package/browser/shared/outline.mjs +194 -0
- package/browser/shared/page-address.mjs +140 -0
- package/browser/shared/page-links.mjs +86 -0
- package/browser/shared/paths.mjs +73 -0
- package/browser/shared/preferences.mjs +116 -0
- package/browser/shared/preview-server.mjs +247 -0
- package/browser/shared/qa-levels.mjs +93 -0
- package/browser/shared/reading-place.mjs +91 -0
- package/browser/shared/renamed-storage.mjs +220 -0
- package/browser/shared/reports.mjs +46 -0
- package/browser/shared/search.mjs +85 -0
- package/browser/shared/session.mjs +77 -0
- package/browser/shared/table-chart.mjs +113 -0
- package/browser/shared/table-hides.mjs +120 -0
- package/browser/shared/table-slots.mjs +75 -0
- package/browser/shared/words.mjs +23 -0
- package/browser/shared/workspace-look.mjs +91 -0
- package/browser/shared/workspace.mjs +535 -0
- package/browser/shared/writing-preferences.mjs +68 -0
- package/browser/shared/zoom.mjs +57 -0
- package/dist/chunk-2B5E4CDJ.mjs +2 -0
- package/dist/chunk-342HXE3Q.mjs +2 -0
- package/dist/chunk-3HIRPVLU.mjs +2 -0
- package/dist/chunk-43B75J5T.mjs +2 -0
- package/dist/chunk-4FS7Z7WR.mjs +2 -0
- package/dist/chunk-4K5KC6V2.mjs +2 -0
- package/dist/chunk-5L7RYZCL.mjs +2 -0
- package/dist/chunk-5MHMDLZD.mjs +4 -0
- package/dist/chunk-5ZKJ3H4P.mjs +8 -0
- package/dist/chunk-64K7IPLO.mjs +255 -0
- package/dist/chunk-6QXGZM36.mjs +8 -0
- package/dist/chunk-6RGJOMJP.mjs +16 -0
- package/dist/chunk-742D2WWJ.mjs +19 -0
- package/dist/chunk-7DTINW6U.mjs +48 -0
- package/dist/chunk-A55HN5OK.mjs +2 -0
- package/dist/chunk-AGDILNWB.mjs +2 -0
- package/dist/chunk-AJ73XJF3.mjs +2 -0
- package/dist/chunk-AUZGSZJH.mjs +13 -0
- package/dist/chunk-BFE45AKL.mjs +2 -0
- package/dist/chunk-BGGDRNYQ.mjs +10 -0
- package/dist/chunk-BXO2ZY5P.mjs +2 -0
- package/dist/chunk-C564NU2H.mjs +77 -0
- package/dist/chunk-CEH4MRCC.mjs +2 -0
- package/dist/chunk-CY2FNNAB.mjs +16 -0
- package/dist/chunk-DFUDV4LX.mjs +2 -0
- package/dist/chunk-DKXG4XDG.mjs +2 -0
- package/dist/chunk-E7LWZRXY.mjs +4 -0
- package/dist/chunk-EZQ34M3F.mjs +124 -0
- package/dist/chunk-EZY3WC6Z.mjs +15 -0
- package/dist/chunk-FDLXYYG4.mjs +4 -0
- package/dist/chunk-FUKQNOQS.mjs +9 -0
- package/dist/chunk-GB5SOYQJ.mjs +7 -0
- package/dist/chunk-GRAXKKG4.mjs +2 -0
- package/dist/chunk-HYMEEXKN.mjs +4 -0
- package/dist/chunk-IVDLMMBD.mjs +2 -0
- package/dist/chunk-JPOSLGOC.mjs +6 -0
- package/dist/chunk-JVHHHGEA.mjs +3 -0
- package/dist/chunk-L3QKH4OK.mjs +26 -0
- package/dist/chunk-LAE5NQ4B.mjs +2 -0
- package/dist/chunk-LCTHTZIL.mjs +960 -0
- package/dist/chunk-LEF6DRCK.mjs +59 -0
- package/dist/chunk-LKX55H76.mjs +2 -0
- package/dist/chunk-LS4F7JUM.mjs +2 -0
- package/dist/chunk-MAFIGVXY.mjs +2 -0
- package/dist/chunk-NO5NJCHO.mjs +2 -0
- package/dist/chunk-NQPVAU63.mjs +2 -0
- package/dist/chunk-NSKUTQ5J.mjs +5 -0
- package/dist/chunk-O35FIXRB.mjs +2 -0
- package/dist/chunk-P2CAZPDP.mjs +3 -0
- package/dist/chunk-PL6GHLGD.mjs +15 -0
- package/dist/chunk-QAIHRH3I.mjs +13 -0
- package/dist/chunk-QJIR2BLP.mjs +6 -0
- package/dist/chunk-QR6A54KJ.mjs +3 -0
- package/dist/chunk-QUPLVPB2.mjs +7 -0
- package/dist/chunk-R7BNENLY.mjs +4 -0
- package/dist/chunk-S6O4UHLC.mjs +2 -0
- package/dist/chunk-SGJWQKEI.mjs +2 -0
- package/dist/chunk-SYGN7GLU.mjs +2 -0
- package/dist/chunk-TMYZB6AV.mjs +2 -0
- package/dist/chunk-TX6JH7TR.mjs +2 -0
- package/dist/chunk-TYK6VNAB.mjs +10 -0
- package/dist/chunk-U3SSPL4K.mjs +8 -0
- package/dist/chunk-U6KNPJPR.mjs +2 -0
- package/dist/chunk-UALRNVSE.mjs +4 -0
- package/dist/chunk-UH4SIXTR.mjs +2 -0
- package/dist/chunk-UMHUSOPJ.mjs +2 -0
- package/dist/chunk-V3HXVQEM.mjs +2 -0
- package/dist/chunk-V5JTW2LH.mjs +27 -0
- package/dist/chunk-V5VXUJKG.mjs +2 -0
- package/dist/chunk-V6XZ4VIR.mjs +2 -0
- package/dist/chunk-VBXMADMP.mjs +2 -0
- package/dist/chunk-VNV55RUA.mjs +2 -0
- package/dist/chunk-VPD2PS35.mjs +2 -0
- package/dist/chunk-W3BGBJQW.mjs +2 -0
- package/dist/chunk-W4VKN3GF.mjs +7 -0
- package/dist/chunk-W5BXXPDJ.mjs +3 -0
- package/dist/chunk-W7XHE4CT.mjs +2 -0
- package/dist/chunk-XNROSH2T.mjs +4 -0
- package/dist/chunk-XUNHRCOG.mjs +6 -0
- package/dist/chunk-Y34NR5JL.mjs +2 -0
- package/dist/chunk-Y6RLRPG3.mjs +3 -0
- package/dist/chunk-YEY3RSFQ.mjs +2 -0
- package/dist/cli.mjs +2 -0
- package/dist/server.mjs +2 -0
- package/dist/worker.mjs +5 -0
- package/kit/charts.js +355 -0
- package/kit/code.js +164 -0
- package/kit/dialogs.js +157 -0
- package/kit/math.js +2004 -0
- package/kit/report.css +2932 -0
- package/kit/runtime.js +1782 -0
- package/kit/sheets.js +123 -0
- package/kit/state.js +217 -0
- package/kit/tables.js +1499 -0
- package/kit/tokens.js +29 -0
- package/kit/ui.js +658 -0
- package/package.json +41 -4
- package/release.json +25 -0
- package/sdk/column-widths.d.ts +56 -0
- package/sdk/doc-charts.d.ts +82 -0
- package/sdk/doc-code.d.ts +28 -0
- package/sdk/doc-dialogs.d.ts +4 -0
- package/sdk/doc-kit.d.ts +147 -0
- package/sdk/doc-math.d.ts +3 -0
- package/sdk/doc-sheets.d.ts +15 -0
- package/sdk/doc-state.d.ts +41 -0
- package/sdk/doc-tables.d.ts +24 -0
- package/sdk/doc-tokens.d.ts +22 -0
- package/sdk/index.d.ts +30 -0
- package/skill/SKILL.md +150 -0
- package/skill/agents/openai.yaml +5 -0
- package/skill/references/building-components.md +367 -0
- package/skill/references/example-report.html +356 -0
- package/skill/references/writing-html.md +187 -0
- package/skill/sdk/column-widths.d.ts +56 -0
- package/skill/sdk/doc-charts.d.ts +82 -0
- package/skill/sdk/doc-code.d.ts +28 -0
- package/skill/sdk/doc-dialogs.d.ts +4 -0
- package/skill/sdk/doc-kit.d.ts +147 -0
- package/skill/sdk/doc-math.d.ts +3 -0
- package/skill/sdk/doc-sheets.d.ts +15 -0
- package/skill/sdk/doc-state.d.ts +41 -0
- package/skill/sdk/doc-tables.d.ts +24 -0
- package/skill/sdk/doc-tokens.d.ts +22 -0
- package/skill/sdk/index.d.ts +30 -0
- package/starter/doc.html +21 -0
- package/starter/doc.json +5 -0
- package/vendor/d3.v7.9.0.min.js +2 -0
- package/vendor/katex/auto-render.min.js +1 -0
- package/vendor/katex/contrib/mhchem.min.js +1 -0
- package/vendor/katex/fonts/KaTeX_AMS-Regular.woff2 +0 -0
- package/vendor/katex/fonts/KaTeX_Caligraphic-Bold.woff2 +0 -0
- package/vendor/katex/fonts/KaTeX_Caligraphic-Regular.woff2 +0 -0
- package/vendor/katex/fonts/KaTeX_Fraktur-Bold.woff2 +0 -0
- package/vendor/katex/fonts/KaTeX_Fraktur-Regular.woff2 +0 -0
- package/vendor/katex/fonts/KaTeX_Main-Bold.woff2 +0 -0
- package/vendor/katex/fonts/KaTeX_Main-BoldItalic.woff2 +0 -0
- package/vendor/katex/fonts/KaTeX_Main-Italic.woff2 +0 -0
- package/vendor/katex/fonts/KaTeX_Main-Regular.woff2 +0 -0
- package/vendor/katex/fonts/KaTeX_Math-BoldItalic.woff2 +0 -0
- package/vendor/katex/fonts/KaTeX_Math-Italic.woff2 +0 -0
- package/vendor/katex/fonts/KaTeX_SansSerif-Bold.woff2 +0 -0
- package/vendor/katex/fonts/KaTeX_SansSerif-Italic.woff2 +0 -0
- package/vendor/katex/fonts/KaTeX_SansSerif-Regular.woff2 +0 -0
- package/vendor/katex/fonts/KaTeX_Script-Regular.woff2 +0 -0
- package/vendor/katex/fonts/KaTeX_Size1-Regular.woff2 +0 -0
- package/vendor/katex/fonts/KaTeX_Size2-Regular.woff2 +0 -0
- package/vendor/katex/fonts/KaTeX_Size3-Regular.woff2 +0 -0
- package/vendor/katex/fonts/KaTeX_Size4-Regular.woff2 +0 -0
- package/vendor/katex/fonts/KaTeX_Typewriter-Regular.woff2 +0 -0
- package/vendor/katex/katex.min.css +1 -0
- package/vendor/katex/katex.min.js +1 -0
- package/vendor/pdfjs/LICENSE +177 -0
- package/vendor/pdfjs/cmaps/78-EUC-H.bcmap +0 -0
- package/vendor/pdfjs/cmaps/78-EUC-V.bcmap +0 -0
- package/vendor/pdfjs/cmaps/78-H.bcmap +0 -0
- package/vendor/pdfjs/cmaps/78-RKSJ-H.bcmap +0 -0
- package/vendor/pdfjs/cmaps/78-RKSJ-V.bcmap +0 -0
- package/vendor/pdfjs/cmaps/78-V.bcmap +0 -0
- package/vendor/pdfjs/cmaps/78ms-RKSJ-H.bcmap +0 -0
- package/vendor/pdfjs/cmaps/78ms-RKSJ-V.bcmap +0 -0
- package/vendor/pdfjs/cmaps/83pv-RKSJ-H.bcmap +0 -0
- package/vendor/pdfjs/cmaps/90ms-RKSJ-H.bcmap +0 -0
- package/vendor/pdfjs/cmaps/90ms-RKSJ-V.bcmap +0 -0
- package/vendor/pdfjs/cmaps/90msp-RKSJ-H.bcmap +0 -0
- package/vendor/pdfjs/cmaps/90msp-RKSJ-V.bcmap +0 -0
- package/vendor/pdfjs/cmaps/90pv-RKSJ-H.bcmap +0 -0
- package/vendor/pdfjs/cmaps/90pv-RKSJ-V.bcmap +0 -0
- package/vendor/pdfjs/cmaps/Add-H.bcmap +0 -0
- package/vendor/pdfjs/cmaps/Add-RKSJ-H.bcmap +0 -0
- package/vendor/pdfjs/cmaps/Add-RKSJ-V.bcmap +0 -0
- package/vendor/pdfjs/cmaps/Add-V.bcmap +0 -0
- package/vendor/pdfjs/cmaps/Adobe-CNS1-0.bcmap +0 -0
- package/vendor/pdfjs/cmaps/Adobe-CNS1-1.bcmap +0 -0
- package/vendor/pdfjs/cmaps/Adobe-CNS1-2.bcmap +0 -0
- package/vendor/pdfjs/cmaps/Adobe-CNS1-3.bcmap +0 -0
- package/vendor/pdfjs/cmaps/Adobe-CNS1-4.bcmap +0 -0
- package/vendor/pdfjs/cmaps/Adobe-CNS1-5.bcmap +0 -0
- package/vendor/pdfjs/cmaps/Adobe-CNS1-6.bcmap +0 -0
- package/vendor/pdfjs/cmaps/Adobe-CNS1-UCS2.bcmap +0 -0
- package/vendor/pdfjs/cmaps/Adobe-GB1-0.bcmap +0 -0
- package/vendor/pdfjs/cmaps/Adobe-GB1-1.bcmap +0 -0
- package/vendor/pdfjs/cmaps/Adobe-GB1-2.bcmap +0 -0
- package/vendor/pdfjs/cmaps/Adobe-GB1-3.bcmap +0 -0
- package/vendor/pdfjs/cmaps/Adobe-GB1-4.bcmap +0 -0
- package/vendor/pdfjs/cmaps/Adobe-GB1-5.bcmap +0 -0
- package/vendor/pdfjs/cmaps/Adobe-GB1-UCS2.bcmap +0 -0
- package/vendor/pdfjs/cmaps/Adobe-Japan1-0.bcmap +0 -0
- package/vendor/pdfjs/cmaps/Adobe-Japan1-1.bcmap +0 -0
- package/vendor/pdfjs/cmaps/Adobe-Japan1-2.bcmap +0 -0
- package/vendor/pdfjs/cmaps/Adobe-Japan1-3.bcmap +0 -0
- package/vendor/pdfjs/cmaps/Adobe-Japan1-4.bcmap +0 -0
- package/vendor/pdfjs/cmaps/Adobe-Japan1-5.bcmap +0 -0
- package/vendor/pdfjs/cmaps/Adobe-Japan1-6.bcmap +0 -0
- package/vendor/pdfjs/cmaps/Adobe-Japan1-UCS2.bcmap +0 -0
- package/vendor/pdfjs/cmaps/Adobe-Korea1-0.bcmap +0 -0
- package/vendor/pdfjs/cmaps/Adobe-Korea1-1.bcmap +0 -0
- package/vendor/pdfjs/cmaps/Adobe-Korea1-2.bcmap +0 -0
- package/vendor/pdfjs/cmaps/Adobe-Korea1-UCS2.bcmap +0 -0
- package/vendor/pdfjs/cmaps/B5-H.bcmap +0 -0
- package/vendor/pdfjs/cmaps/B5-V.bcmap +0 -0
- package/vendor/pdfjs/cmaps/B5pc-H.bcmap +0 -0
- package/vendor/pdfjs/cmaps/B5pc-V.bcmap +0 -0
- package/vendor/pdfjs/cmaps/CNS-EUC-H.bcmap +0 -0
- package/vendor/pdfjs/cmaps/CNS-EUC-V.bcmap +0 -0
- package/vendor/pdfjs/cmaps/CNS1-H.bcmap +0 -0
- package/vendor/pdfjs/cmaps/CNS1-V.bcmap +0 -0
- package/vendor/pdfjs/cmaps/CNS2-H.bcmap +0 -0
- package/vendor/pdfjs/cmaps/CNS2-V.bcmap +3 -0
- package/vendor/pdfjs/cmaps/ETHK-B5-H.bcmap +0 -0
- package/vendor/pdfjs/cmaps/ETHK-B5-V.bcmap +0 -0
- package/vendor/pdfjs/cmaps/ETen-B5-H.bcmap +0 -0
- package/vendor/pdfjs/cmaps/ETen-B5-V.bcmap +0 -0
- package/vendor/pdfjs/cmaps/ETenms-B5-H.bcmap +3 -0
- package/vendor/pdfjs/cmaps/ETenms-B5-V.bcmap +0 -0
- package/vendor/pdfjs/cmaps/EUC-H.bcmap +0 -0
- package/vendor/pdfjs/cmaps/EUC-V.bcmap +0 -0
- package/vendor/pdfjs/cmaps/Ext-H.bcmap +0 -0
- package/vendor/pdfjs/cmaps/Ext-RKSJ-H.bcmap +0 -0
- package/vendor/pdfjs/cmaps/Ext-RKSJ-V.bcmap +0 -0
- package/vendor/pdfjs/cmaps/Ext-V.bcmap +0 -0
- package/vendor/pdfjs/cmaps/GB-EUC-H.bcmap +0 -0
- package/vendor/pdfjs/cmaps/GB-EUC-V.bcmap +0 -0
- package/vendor/pdfjs/cmaps/GB-H.bcmap +4 -0
- package/vendor/pdfjs/cmaps/GB-V.bcmap +0 -0
- package/vendor/pdfjs/cmaps/GBK-EUC-H.bcmap +0 -0
- package/vendor/pdfjs/cmaps/GBK-EUC-V.bcmap +0 -0
- package/vendor/pdfjs/cmaps/GBK2K-H.bcmap +0 -0
- package/vendor/pdfjs/cmaps/GBK2K-V.bcmap +0 -0
- package/vendor/pdfjs/cmaps/GBKp-EUC-H.bcmap +0 -0
- package/vendor/pdfjs/cmaps/GBKp-EUC-V.bcmap +0 -0
- package/vendor/pdfjs/cmaps/GBT-EUC-H.bcmap +0 -0
- package/vendor/pdfjs/cmaps/GBT-EUC-V.bcmap +0 -0
- package/vendor/pdfjs/cmaps/GBT-H.bcmap +0 -0
- package/vendor/pdfjs/cmaps/GBT-V.bcmap +0 -0
- package/vendor/pdfjs/cmaps/GBTpc-EUC-H.bcmap +0 -0
- package/vendor/pdfjs/cmaps/GBTpc-EUC-V.bcmap +0 -0
- package/vendor/pdfjs/cmaps/GBpc-EUC-H.bcmap +0 -0
- package/vendor/pdfjs/cmaps/GBpc-EUC-V.bcmap +0 -0
- package/vendor/pdfjs/cmaps/H.bcmap +0 -0
- package/vendor/pdfjs/cmaps/HKdla-B5-H.bcmap +0 -0
- package/vendor/pdfjs/cmaps/HKdla-B5-V.bcmap +0 -0
- package/vendor/pdfjs/cmaps/HKdlb-B5-H.bcmap +0 -0
- package/vendor/pdfjs/cmaps/HKdlb-B5-V.bcmap +0 -0
- package/vendor/pdfjs/cmaps/HKgccs-B5-H.bcmap +0 -0
- package/vendor/pdfjs/cmaps/HKgccs-B5-V.bcmap +0 -0
- package/vendor/pdfjs/cmaps/HKm314-B5-H.bcmap +0 -0
- package/vendor/pdfjs/cmaps/HKm314-B5-V.bcmap +0 -0
- package/vendor/pdfjs/cmaps/HKm471-B5-H.bcmap +0 -0
- package/vendor/pdfjs/cmaps/HKm471-B5-V.bcmap +0 -0
- package/vendor/pdfjs/cmaps/HKscs-B5-H.bcmap +0 -0
- package/vendor/pdfjs/cmaps/HKscs-B5-V.bcmap +0 -0
- package/vendor/pdfjs/cmaps/Hankaku.bcmap +0 -0
- package/vendor/pdfjs/cmaps/Hiragana.bcmap +0 -0
- package/vendor/pdfjs/cmaps/KSC-EUC-H.bcmap +0 -0
- package/vendor/pdfjs/cmaps/KSC-EUC-V.bcmap +0 -0
- package/vendor/pdfjs/cmaps/KSC-H.bcmap +0 -0
- package/vendor/pdfjs/cmaps/KSC-Johab-H.bcmap +0 -0
- package/vendor/pdfjs/cmaps/KSC-Johab-V.bcmap +0 -0
- package/vendor/pdfjs/cmaps/KSC-V.bcmap +0 -0
- package/vendor/pdfjs/cmaps/KSCms-UHC-H.bcmap +0 -0
- package/vendor/pdfjs/cmaps/KSCms-UHC-HW-H.bcmap +0 -0
- package/vendor/pdfjs/cmaps/KSCms-UHC-HW-V.bcmap +0 -0
- package/vendor/pdfjs/cmaps/KSCms-UHC-V.bcmap +0 -0
- package/vendor/pdfjs/cmaps/KSCpc-EUC-H.bcmap +0 -0
- package/vendor/pdfjs/cmaps/KSCpc-EUC-V.bcmap +0 -0
- package/vendor/pdfjs/cmaps/Katakana.bcmap +0 -0
- package/vendor/pdfjs/cmaps/LICENSE +36 -0
- package/vendor/pdfjs/cmaps/NWP-H.bcmap +0 -0
- package/vendor/pdfjs/cmaps/NWP-V.bcmap +0 -0
- package/vendor/pdfjs/cmaps/RKSJ-H.bcmap +0 -0
- package/vendor/pdfjs/cmaps/RKSJ-V.bcmap +0 -0
- package/vendor/pdfjs/cmaps/Roman.bcmap +0 -0
- package/vendor/pdfjs/cmaps/UniCNS-UCS2-H.bcmap +0 -0
- package/vendor/pdfjs/cmaps/UniCNS-UCS2-V.bcmap +0 -0
- package/vendor/pdfjs/cmaps/UniCNS-UTF16-H.bcmap +0 -0
- package/vendor/pdfjs/cmaps/UniCNS-UTF16-V.bcmap +0 -0
- package/vendor/pdfjs/cmaps/UniCNS-UTF32-H.bcmap +0 -0
- package/vendor/pdfjs/cmaps/UniCNS-UTF32-V.bcmap +0 -0
- package/vendor/pdfjs/cmaps/UniCNS-UTF8-H.bcmap +0 -0
- package/vendor/pdfjs/cmaps/UniCNS-UTF8-V.bcmap +0 -0
- package/vendor/pdfjs/cmaps/UniGB-UCS2-H.bcmap +0 -0
- package/vendor/pdfjs/cmaps/UniGB-UCS2-V.bcmap +0 -0
- package/vendor/pdfjs/cmaps/UniGB-UTF16-H.bcmap +0 -0
- package/vendor/pdfjs/cmaps/UniGB-UTF16-V.bcmap +0 -0
- package/vendor/pdfjs/cmaps/UniGB-UTF32-H.bcmap +0 -0
- package/vendor/pdfjs/cmaps/UniGB-UTF32-V.bcmap +0 -0
- package/vendor/pdfjs/cmaps/UniGB-UTF8-H.bcmap +0 -0
- package/vendor/pdfjs/cmaps/UniGB-UTF8-V.bcmap +0 -0
- package/vendor/pdfjs/cmaps/UniJIS-UCS2-H.bcmap +0 -0
- package/vendor/pdfjs/cmaps/UniJIS-UCS2-HW-H.bcmap +0 -0
- package/vendor/pdfjs/cmaps/UniJIS-UCS2-HW-V.bcmap +0 -0
- package/vendor/pdfjs/cmaps/UniJIS-UCS2-V.bcmap +0 -0
- package/vendor/pdfjs/cmaps/UniJIS-UTF16-H.bcmap +0 -0
- package/vendor/pdfjs/cmaps/UniJIS-UTF16-V.bcmap +0 -0
- package/vendor/pdfjs/cmaps/UniJIS-UTF32-H.bcmap +0 -0
- package/vendor/pdfjs/cmaps/UniJIS-UTF32-V.bcmap +0 -0
- package/vendor/pdfjs/cmaps/UniJIS-UTF8-H.bcmap +0 -0
- package/vendor/pdfjs/cmaps/UniJIS-UTF8-V.bcmap +0 -0
- package/vendor/pdfjs/cmaps/UniJIS2004-UTF16-H.bcmap +0 -0
- package/vendor/pdfjs/cmaps/UniJIS2004-UTF16-V.bcmap +0 -0
- package/vendor/pdfjs/cmaps/UniJIS2004-UTF32-H.bcmap +0 -0
- package/vendor/pdfjs/cmaps/UniJIS2004-UTF32-V.bcmap +0 -0
- package/vendor/pdfjs/cmaps/UniJIS2004-UTF8-H.bcmap +0 -0
- package/vendor/pdfjs/cmaps/UniJIS2004-UTF8-V.bcmap +0 -0
- package/vendor/pdfjs/cmaps/UniJISPro-UCS2-HW-V.bcmap +0 -0
- package/vendor/pdfjs/cmaps/UniJISPro-UCS2-V.bcmap +0 -0
- package/vendor/pdfjs/cmaps/UniJISPro-UTF8-V.bcmap +0 -0
- package/vendor/pdfjs/cmaps/UniJISX0213-UTF32-H.bcmap +0 -0
- package/vendor/pdfjs/cmaps/UniJISX0213-UTF32-V.bcmap +0 -0
- package/vendor/pdfjs/cmaps/UniJISX02132004-UTF32-H.bcmap +0 -0
- package/vendor/pdfjs/cmaps/UniJISX02132004-UTF32-V.bcmap +0 -0
- package/vendor/pdfjs/cmaps/UniKS-UCS2-H.bcmap +0 -0
- package/vendor/pdfjs/cmaps/UniKS-UCS2-V.bcmap +0 -0
- package/vendor/pdfjs/cmaps/UniKS-UTF16-H.bcmap +0 -0
- package/vendor/pdfjs/cmaps/UniKS-UTF16-V.bcmap +0 -0
- package/vendor/pdfjs/cmaps/UniKS-UTF32-H.bcmap +0 -0
- package/vendor/pdfjs/cmaps/UniKS-UTF32-V.bcmap +0 -0
- package/vendor/pdfjs/cmaps/UniKS-UTF8-H.bcmap +0 -0
- package/vendor/pdfjs/cmaps/UniKS-UTF8-V.bcmap +0 -0
- package/vendor/pdfjs/cmaps/V.bcmap +0 -0
- package/vendor/pdfjs/cmaps/WP-Symbol.bcmap +0 -0
- package/vendor/pdfjs/legacy/build/pdf.min.mjs +27 -0
- package/vendor/pdfjs/legacy/build/pdf.worker.min.mjs +27 -0
- package/vendor/pdfjs/standard_fonts/FoxitDingbats.pfb +0 -0
- package/vendor/pdfjs/standard_fonts/FoxitFixed.pfb +0 -0
- package/vendor/pdfjs/standard_fonts/FoxitFixedBold.pfb +0 -0
- package/vendor/pdfjs/standard_fonts/FoxitFixedBoldItalic.pfb +0 -0
- package/vendor/pdfjs/standard_fonts/FoxitFixedItalic.pfb +0 -0
- package/vendor/pdfjs/standard_fonts/FoxitSerif.pfb +0 -0
- package/vendor/pdfjs/standard_fonts/FoxitSerifBold.pfb +0 -0
- package/vendor/pdfjs/standard_fonts/FoxitSerifBoldItalic.pfb +0 -0
- package/vendor/pdfjs/standard_fonts/FoxitSerifItalic.pfb +0 -0
- package/vendor/pdfjs/standard_fonts/FoxitSymbol.pfb +0 -0
- package/vendor/pdfjs/standard_fonts/LICENSE_FOXIT +27 -0
- package/vendor/pdfjs/standard_fonts/LICENSE_LIBERATION +363 -0
- package/vendor/pdfjs/standard_fonts/LiberationSans-Bold.ttf +0 -0
- package/vendor/pdfjs/standard_fonts/LiberationSans-BoldItalic.ttf +0 -0
- package/vendor/pdfjs/standard_fonts/LiberationSans-Italic.ttf +0 -0
- package/vendor/pdfjs/standard_fonts/LiberationSans-Regular.ttf +0 -0
- package/vendor/types/@types/d3/LICENSE +21 -0
- package/vendor/types/@types/d3/index.d.ts +39 -0
- package/vendor/types/@types/d3/package.json +81 -0
- package/vendor/types/@types/d3-array/LICENSE +21 -0
- package/vendor/types/@types/d3-array/index.d.ts +1118 -0
- package/vendor/types/@types/d3-array/package.json +56 -0
- package/vendor/types/@types/d3-axis/LICENSE +21 -0
- package/vendor/types/@types/d3-axis/index.d.ts +293 -0
- package/vendor/types/@types/d3-axis/package.json +47 -0
- package/vendor/types/@types/d3-brush/LICENSE +21 -0
- package/vendor/types/@types/d3-brush/index.d.ts +255 -0
- package/vendor/types/@types/d3-brush/package.json +42 -0
- package/vendor/types/@types/d3-chord/LICENSE +21 -0
- package/vendor/types/@types/d3-chord/index.d.ts +471 -0
- package/vendor/types/@types/d3-chord/package.json +40 -0
- package/vendor/types/@types/d3-color/LICENSE +21 -0
- package/vendor/types/@types/d3-color/index.d.ts +669 -0
- package/vendor/types/@types/d3-color/package.json +55 -0
- package/vendor/types/@types/d3-contour/LICENSE +21 -0
- package/vendor/types/@types/d3-contour/index.d.ts +222 -0
- package/vendor/types/@types/d3-contour/package.json +38 -0
- package/vendor/types/@types/d3-delaunay/LICENSE +21 -0
- package/vendor/types/@types/d3-delaunay/index.d.ts +316 -0
- package/vendor/types/@types/d3-delaunay/package.json +30 -0
- package/vendor/types/@types/d3-dispatch/LICENSE +21 -0
- package/vendor/types/@types/d3-dispatch/index.d.ts +96 -0
- package/vendor/types/@types/d3-dispatch/package.json +51 -0
- package/vendor/types/@types/d3-drag/LICENSE +21 -0
- package/vendor/types/@types/d3-drag/index.d.ts +395 -0
- package/vendor/types/@types/d3-drag/package.json +42 -0
- package/vendor/types/@types/d3-dsv/LICENSE +21 -0
- package/vendor/types/@types/d3-dsv/index.d.ts +482 -0
- package/vendor/types/@types/d3-dsv/package.json +45 -0
- package/vendor/types/@types/d3-ease/LICENSE +21 -0
- package/vendor/types/@types/d3-ease/index.d.ts +316 -0
- package/vendor/types/@types/d3-ease/package.json +40 -0
- package/vendor/types/@types/d3-fetch/LICENSE +21 -0
- package/vendor/types/@types/d3-fetch/index.d.ts +282 -0
- package/vendor/types/@types/d3-fetch/package.json +37 -0
- package/vendor/types/@types/d3-force/LICENSE +21 -0
- package/vendor/types/@types/d3-force/index.d.ts +899 -0
- package/vendor/types/@types/d3-force/package.json +45 -0
- package/vendor/types/@types/d3-format/LICENSE +21 -0
- package/vendor/types/@types/d3-format/index.d.ts +337 -0
- package/vendor/types/@types/d3-format/package.json +45 -0
- package/vendor/types/@types/d3-geo/LICENSE +21 -0
- package/vendor/types/@types/d3-geo/index.d.ts +1371 -0
- package/vendor/types/@types/d3-geo/package.json +48 -0
- package/vendor/types/@types/d3-hierarchy/LICENSE +21 -0
- package/vendor/types/@types/d3-hierarchy/index.d.ts +928 -0
- package/vendor/types/@types/d3-hierarchy/package.json +50 -0
- package/vendor/types/@types/d3-interpolate/LICENSE +21 -0
- package/vendor/types/@types/d3-interpolate/index.d.ts +387 -0
- package/vendor/types/@types/d3-interpolate/package.json +47 -0
- package/vendor/types/@types/d3-path/LICENSE +21 -0
- package/vendor/types/@types/d3-path/index.d.ts +108 -0
- package/vendor/types/@types/d3-path/package.json +41 -0
- package/vendor/types/@types/d3-polygon/LICENSE +21 -0
- package/vendor/types/@types/d3-polygon/index.d.ts +41 -0
- package/vendor/types/@types/d3-polygon/package.json +40 -0
- package/vendor/types/@types/d3-quadtree/LICENSE +21 -0
- package/vendor/types/@types/d3-quadtree/index.d.ts +204 -0
- package/vendor/types/@types/d3-quadtree/package.json +45 -0
- package/vendor/types/@types/d3-random/LICENSE +21 -0
- package/vendor/types/@types/d3-random/index.d.ts +313 -0
- package/vendor/types/@types/d3-random/package.json +41 -0
- package/vendor/types/@types/d3-scale/LICENSE +21 -0
- package/vendor/types/@types/d3-scale/index.d.ts +2669 -0
- package/vendor/types/@types/d3-scale/package.json +53 -0
- package/vendor/types/@types/d3-scale-chromatic/LICENSE +21 -0
- package/vendor/types/@types/d3-scale-chromatic/index.d.ts +520 -0
- package/vendor/types/@types/d3-scale-chromatic/package.json +46 -0
- package/vendor/types/@types/d3-selection/LICENSE +21 -0
- package/vendor/types/@types/d3-selection/index.d.ts +1210 -0
- package/vendor/types/@types/d3-selection/package.json +56 -0
- package/vendor/types/@types/d3-shape/LICENSE +21 -0
- package/vendor/types/@types/d3-shape/index.d.ts +2792 -0
- package/vendor/types/@types/d3-shape/package.json +53 -0
- package/vendor/types/@types/d3-time/LICENSE +21 -0
- package/vendor/types/@types/d3-time/index.d.ts +697 -0
- package/vendor/types/@types/d3-time/package.json +46 -0
- package/vendor/types/@types/d3-time-format/LICENSE +21 -0
- package/vendor/types/@types/d3-time-format/index.d.ts +202 -0
- package/vendor/types/@types/d3-time-format/package.json +40 -0
- package/vendor/types/@types/d3-timer/LICENSE +21 -0
- package/vendor/types/@types/d3-timer/index.d.ts +68 -0
- package/vendor/types/@types/d3-timer/package.json +45 -0
- package/vendor/types/@types/d3-transition/LICENSE +21 -0
- package/vendor/types/@types/d3-transition/index.d.ts +664 -0
- package/vendor/types/@types/d3-transition/package.json +47 -0
- package/vendor/types/@types/d3-zoom/LICENSE +21 -0
- package/vendor/types/@types/d3-zoom/index.d.ts +611 -0
- package/vendor/types/@types/d3-zoom/package.json +48 -0
- package/vendor/types/@types/geojson/LICENSE +21 -0
- package/vendor/types/@types/geojson/index.d.ts +202 -0
- package/vendor/types/@types/geojson/package.json +46 -0
- package/vendor/typescript/LICENSE.txt +55 -0
- package/vendor/typescript/lib.decorators.d.ts +384 -0
- package/vendor/typescript/lib.decorators.legacy.d.ts +22 -0
- package/vendor/typescript/lib.dom.d.ts +39429 -0
- package/vendor/typescript/lib.dom.iterable.d.ts +571 -0
- package/vendor/typescript/lib.es2015.collection.d.ts +147 -0
- package/vendor/typescript/lib.es2015.core.d.ts +597 -0
- package/vendor/typescript/lib.es2015.d.ts +28 -0
- package/vendor/typescript/lib.es2015.generator.d.ts +77 -0
- package/vendor/typescript/lib.es2015.iterable.d.ts +605 -0
- package/vendor/typescript/lib.es2015.promise.d.ts +81 -0
- package/vendor/typescript/lib.es2015.proxy.d.ts +128 -0
- package/vendor/typescript/lib.es2015.reflect.d.ts +144 -0
- package/vendor/typescript/lib.es2015.symbol.d.ts +46 -0
- package/vendor/typescript/lib.es2015.symbol.wellknown.d.ts +326 -0
- package/vendor/typescript/lib.es2016.array.include.d.ts +116 -0
- package/vendor/typescript/lib.es2016.d.ts +21 -0
- package/vendor/typescript/lib.es2016.intl.d.ts +31 -0
- package/vendor/typescript/lib.es2017.arraybuffer.d.ts +21 -0
- package/vendor/typescript/lib.es2017.d.ts +26 -0
- package/vendor/typescript/lib.es2017.date.d.ts +31 -0
- package/vendor/typescript/lib.es2017.intl.d.ts +44 -0
- package/vendor/typescript/lib.es2017.object.d.ts +49 -0
- package/vendor/typescript/lib.es2017.sharedmemory.d.ts +135 -0
- package/vendor/typescript/lib.es2017.string.d.ts +45 -0
- package/vendor/typescript/lib.es2017.typedarrays.d.ts +53 -0
- package/vendor/typescript/lib.es2018.asyncgenerator.d.ts +77 -0
- package/vendor/typescript/lib.es2018.asynciterable.d.ts +53 -0
- package/vendor/typescript/lib.es2018.d.ts +24 -0
- package/vendor/typescript/lib.es2018.intl.d.ts +83 -0
- package/vendor/typescript/lib.es2018.promise.d.ts +30 -0
- package/vendor/typescript/lib.es2018.regexp.d.ts +37 -0
- package/vendor/typescript/lib.es2019.array.d.ts +79 -0
- package/vendor/typescript/lib.es2019.d.ts +24 -0
- package/vendor/typescript/lib.es2019.intl.d.ts +23 -0
- package/vendor/typescript/lib.es2019.object.d.ts +33 -0
- package/vendor/typescript/lib.es2019.string.d.ts +37 -0
- package/vendor/typescript/lib.es2019.symbol.d.ts +24 -0
- package/vendor/typescript/lib.es2020.bigint.d.ts +765 -0
- package/vendor/typescript/lib.es2020.d.ts +27 -0
- package/vendor/typescript/lib.es2020.date.d.ts +42 -0
- package/vendor/typescript/lib.es2020.intl.d.ts +474 -0
- package/vendor/typescript/lib.es2020.number.d.ts +28 -0
- package/vendor/typescript/lib.es2020.promise.d.ts +47 -0
- package/vendor/typescript/lib.es2020.sharedmemory.d.ts +99 -0
- package/vendor/typescript/lib.es2020.string.d.ts +44 -0
- package/vendor/typescript/lib.es2020.symbol.wellknown.d.ts +41 -0
- package/vendor/typescript/lib.es2021.d.ts +23 -0
- package/vendor/typescript/lib.es2021.intl.d.ts +166 -0
- package/vendor/typescript/lib.es2021.promise.d.ts +48 -0
- package/vendor/typescript/lib.es2021.string.d.ts +33 -0
- package/vendor/typescript/lib.es2021.weakref.d.ts +78 -0
- package/vendor/typescript/lib.es2022.array.d.ts +121 -0
- package/vendor/typescript/lib.es2022.d.ts +25 -0
- package/vendor/typescript/lib.es2022.error.d.ts +75 -0
- package/vendor/typescript/lib.es2022.intl.d.ts +145 -0
- package/vendor/typescript/lib.es2022.object.d.ts +26 -0
- package/vendor/typescript/lib.es2022.regexp.d.ts +39 -0
- package/vendor/typescript/lib.es2022.string.d.ts +25 -0
- package/vendor/typescript/lib.es5.d.ts +4601 -0
- package/vendor/typescript/package.json +4 -0
- package/vendor/typescript/typescript.js +446 -0
- package/web/assets/index-Bh74DfsV.css +1 -0
- package/web/assets/index-UW0RyFFt.js +13 -0
- package/web/index.html +14 -0
|
@@ -0,0 +1,682 @@
|
|
|
1
|
+
import { DIALOG } from "../components/kit.mjs";
|
|
2
|
+
import { SEALED, texOnly } from "../components/registry.mjs";
|
|
3
|
+
import { slotsOf } from "../../shared/table-slots.mjs";
|
|
4
|
+
import { isHost, nestedBlocks, textEnd } from "./core.mjs";
|
|
5
|
+
import { pageAt } from "./page-objects.mjs";
|
|
6
|
+
|
|
7
|
+
// Caret and line helpers of the preview editor: where the caret is, the lines of a block, the
|
|
8
|
+
// block above or below, and moving between blocks with the arrow keys (editor.mjs handles the keys).
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* The editable block (a contenteditable host) a node is in, or null. What stands in what is sealed
|
|
12
|
+
* (`sealed`: an instance of a component package) is no text of a text block around that: a list item
|
|
13
|
+
* holding it is that to closest, whatever contenteditable="false" says between them.
|
|
14
|
+
*/
|
|
15
|
+
export const editable = (node) => {
|
|
16
|
+
const start = node?.nodeType === 1 ? node : node?.parentElement;
|
|
17
|
+
const host = start?.closest?.('[contenteditable="true"]');
|
|
18
|
+
if (!isHost(host)) return null;
|
|
19
|
+
const seal = SEALED ? node.parentElement?.closest(SEALED) : null;
|
|
20
|
+
return seal && !seal.contains(host) ? null : host;
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* The text block holding the caret inside text block `outer`, or `outer`: a list item holding a
|
|
25
|
+
* paragraph (or a heading) is edited by Chrome as one editable element, the outermost, which then has
|
|
26
|
+
* the focus and gets the paragraph's keys, input and paste; the caret tells which block they are for.
|
|
27
|
+
*/
|
|
28
|
+
export function innerHost(outer) {
|
|
29
|
+
const selection = getSelection();
|
|
30
|
+
const inner = selection.rangeCount ? editable(selection.anchorNode) : null;
|
|
31
|
+
return inner && outer && inner !== outer && outer.contains(inner) ? inner : outer;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/** The text block an event (a key, input, a paste) is for: the one around its target, or the caret's inside it (innerHost). */
|
|
35
|
+
export const hostOf = (event) => innerHost(editable(event.target));
|
|
36
|
+
|
|
37
|
+
export function select(range) {
|
|
38
|
+
const selection = getSelection();
|
|
39
|
+
selection.removeAllRanges();
|
|
40
|
+
selection.addRange(range);
|
|
41
|
+
// Chrome may keep the caret it put at the start of a text block just focused, removeAllRanges and
|
|
42
|
+
// all, and then takes no range added (a list item Tab moved into the list the item above holds,
|
|
43
|
+
// where the caret went back to its start): the range replaces it.
|
|
44
|
+
const now = selection.rangeCount ? selection.getRangeAt(0) : null;
|
|
45
|
+
if (!now || now.startContainer !== range.startContainer || now.startOffset !== range.startOffset || now.endContainer !== range.endContainer || now.endOffset !== range.endOffset) {
|
|
46
|
+
selection.setBaseAndExtent(range.startContainer, range.startOffset, range.endContainer, range.endOffset);
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
/** The chip of the text `node` is in, or null. */
|
|
51
|
+
export const atomOf = (node) => (node?.nodeType === 1 ? node : node?.parentElement)?.closest?.("[data-ge-atom]") ?? null;
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* A caret inside a formula, where nothing can be typed: a click right of one whose superscript
|
|
55
|
+
* reaches past its text (\mathbb{R}^n, x^2) puts it in the formula's own text. It goes after the
|
|
56
|
+
* formula, or before it when `x` (the click) is on its left half. Returns whether it moved.
|
|
57
|
+
*/
|
|
58
|
+
export function outOfAtom(x = null) {
|
|
59
|
+
const selection = getSelection();
|
|
60
|
+
if (!selection.rangeCount || !selection.isCollapsed) return false;
|
|
61
|
+
const atom = atomOf(selection.anchorNode);
|
|
62
|
+
if (!atom) return false;
|
|
63
|
+
const rect = atom.getBoundingClientRect();
|
|
64
|
+
const range = document.createRange();
|
|
65
|
+
besideAtom(range, atom, x === null || x >= rect.left + rect.width / 2);
|
|
66
|
+
select(range);
|
|
67
|
+
return true;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
// Where a block's text ends: before the blocks an item holds, and before the line break that keeps an
|
|
71
|
+
// empty item's line ahead of them (keepLine), past which there is no line of its, only theirs.
|
|
72
|
+
const lineEnd = (host) => {
|
|
73
|
+
const end = textEnd(host);
|
|
74
|
+
return end < host.childNodes.length && host.childNodes[end - 1]?.nodeName === "BR" ? end - 1 : end;
|
|
75
|
+
};
|
|
76
|
+
|
|
77
|
+
/** The caret at a block's start or end, the page staying where it is (notion-lite's focusBlockText). Returns whether it went there. */
|
|
78
|
+
export function placeCaret(host, where, offset = null) {
|
|
79
|
+
if (!host?.isConnected) return false;
|
|
80
|
+
host.focus({ preventScroll: true });
|
|
81
|
+
const range = document.createRange();
|
|
82
|
+
range.setStart(host, offset !== null ? Math.min(offset, host.childNodes.length) : where === "start" ? 0 : lineEnd(host));
|
|
83
|
+
range.collapse(true);
|
|
84
|
+
select(range);
|
|
85
|
+
return true;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
export function caretAt(host, where, offset = null) {
|
|
89
|
+
if (!placeCaret(host, where, offset)) return;
|
|
90
|
+
host.scrollIntoView({ block: "nearest", inline: "nearest" });
|
|
91
|
+
showEnd(); // a detail card's last block: its content to the end
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
/** Put the caret after this many characters of a block. */
|
|
95
|
+
export function caretAtOffset(host, offset) {
|
|
96
|
+
const walker = document.createTreeWalker(host, NodeFilter.SHOW_TEXT);
|
|
97
|
+
let rest = offset;
|
|
98
|
+
let last = null;
|
|
99
|
+
for (let node = walker.nextNode(); node; node = walker.nextNode()) {
|
|
100
|
+
if (rest <= node.length) {
|
|
101
|
+
const caret = document.createRange();
|
|
102
|
+
caret.setStart(node, rest);
|
|
103
|
+
return select(caret);
|
|
104
|
+
}
|
|
105
|
+
rest -= node.length;
|
|
106
|
+
last = node;
|
|
107
|
+
}
|
|
108
|
+
if (last) caretAt(host, "end");
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
/** The selection when it is non-empty and inside a single block: { host, range }, or null. */
|
|
112
|
+
export function selectionContext() {
|
|
113
|
+
const selection = getSelection();
|
|
114
|
+
if (!selection.rangeCount || selection.isCollapsed) return null;
|
|
115
|
+
const range = selection.getRangeAt(0);
|
|
116
|
+
const host = editable(range.startContainer);
|
|
117
|
+
return host && editable(range.endContainer) === host ? { host, range } : null;
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
function edgeRange(host, toEnd) {
|
|
121
|
+
const selection = getSelection();
|
|
122
|
+
if (!selection.rangeCount || !selection.isCollapsed) return null;
|
|
123
|
+
const range = document.createRange();
|
|
124
|
+
if (toEnd) {
|
|
125
|
+
range.setStart(selection.anchorNode, selection.anchorOffset);
|
|
126
|
+
range.setEnd(host, textEnd(host));
|
|
127
|
+
} else {
|
|
128
|
+
range.setStart(host, 0);
|
|
129
|
+
range.setEnd(selection.anchorNode, selection.anchorOffset);
|
|
130
|
+
}
|
|
131
|
+
return range;
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
// Nothing (no text, formula or line break) between the caret and the block edge. A <br> the
|
|
135
|
+
// browser keeps at the very end of a block to hold its last line does not count.
|
|
136
|
+
export function atEdge(host, toEnd) {
|
|
137
|
+
const range = edgeRange(host, toEnd);
|
|
138
|
+
if (!range || range.toString() !== "") return false;
|
|
139
|
+
const content = range.cloneContents();
|
|
140
|
+
if (content.querySelector("[data-ge-atom]")) return false;
|
|
141
|
+
return content.querySelectorAll("br").length <= (toEnd && host.childNodes[textEnd(host) - 1]?.nodeName === "BR" ? 1 : 0);
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
// Editable hosts the reader can reach now, in document order: visible, and inside the open
|
|
145
|
+
// modal dialog when there is one. A closed disclosure's content is not (the browser still lays it
|
|
146
|
+
// out, under the title and over the blocks after it, but draws none of it: checkVisibility).
|
|
147
|
+
export function hosts() {
|
|
148
|
+
const scope = document.querySelector("dialog[open]") ?? document;
|
|
149
|
+
return [...scope.querySelectorAll("[data-ge-block], [data-ge-new]")]
|
|
150
|
+
.filter((node) => isHost(node) && shown(node));
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
const shown = (node) => node.getClientRects().length > 0 && !node.closest("[inert]") && node.checkVisibility?.() !== false;
|
|
154
|
+
|
|
155
|
+
/**
|
|
156
|
+
* The text block nearest `host` going `step` (1 on, -1 back) in `list` (hosts()) that has text to type
|
|
157
|
+
* in, or undefined: not a formula block, which has none (notion-lite's adjacentLeaf passes over a block
|
|
158
|
+
* with no text leaf, as the arrow keys do here: places()).
|
|
159
|
+
*/
|
|
160
|
+
export function textNear(host, step, list = hosts()) {
|
|
161
|
+
for (let at = list.indexOf(host) + step; at >= 0 && at < list.length; at += step) if (!texOnly(list[at])) return list[at];
|
|
162
|
+
return undefined;
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
// Where the arrow keys take the caret between blocks, in document order: the editable hosts (hosts())
|
|
166
|
+
// and the code blocks a press opens for editing (a pre marked data-ge-code: components/code/page.mjs
|
|
167
|
+
// openAt), whose code is text to move into, as notion-lite's code leaf is; not a formula block, which
|
|
168
|
+
// has no text to type in (notion-lite's has no text leaf: the keys pass over it, and Enter on it
|
|
169
|
+
// selected opens its editor).
|
|
170
|
+
function places() {
|
|
171
|
+
const scope = document.querySelector("dialog[open]") ?? document;
|
|
172
|
+
const codes = [...scope.querySelectorAll("main pre[data-ge-code]")].filter(shown);
|
|
173
|
+
const list = hosts().filter((node) => !texOnly(node));
|
|
174
|
+
if (codes.length === 0) return list;
|
|
175
|
+
return [...list, ...codes].sort(inOrder);
|
|
176
|
+
}
|
|
177
|
+
const closedCode = (node) => node.localName === "pre";
|
|
178
|
+
const inOrder = (a, b) => (a.compareDocumentPosition(b) & Node.DOCUMENT_POSITION_FOLLOWING ? -1 : 1);
|
|
179
|
+
// Preformatted text (a code block's), where a line break is a line of its own.
|
|
180
|
+
const preformatted = (node) => /^(pre|break-spaces)/.test(getComputedStyle(node.nodeType === 1 ? node : node.parentElement).whiteSpace);
|
|
181
|
+
|
|
182
|
+
// Line boxes of a block: its text and its formula chips (not the glyph boxes inside a formula, nor
|
|
183
|
+
// anything the blocks a list item holds show: a paragraph's words, a task board's drawn labels); of a
|
|
184
|
+
// code block not open yet (a pre), its code's. An empty line of code has a box too, for the caret to
|
|
185
|
+
// stop on: in open code the line break ending it (a break stands at the end of the line it ends), in a
|
|
186
|
+
// code block not open yet the kit's line's content.
|
|
187
|
+
function lineRects(host) {
|
|
188
|
+
const rects = [];
|
|
189
|
+
const range = document.createRange();
|
|
190
|
+
const walker = document.createTreeWalker(host, NodeFilter.SHOW_TEXT);
|
|
191
|
+
const closed = closedCode(host);
|
|
192
|
+
const held = nestedBlocks(host);
|
|
193
|
+
const own = closed ? () => true : (node) => node.parentElement.closest('[contenteditable="true"]') === host && !held.some((block) => block.contains(node));
|
|
194
|
+
const pre = preformatted(host);
|
|
195
|
+
let last = "\n"; // the character before, in the block's own text (its start begins a line)
|
|
196
|
+
for (let node; (node = walker.nextNode());) {
|
|
197
|
+
if (node.parentElement.closest("[data-ge-atom]") || !own(node)) continue;
|
|
198
|
+
for (let at = pre ? node.data.indexOf("\n") : -1; at >= 0; at = node.data.indexOf("\n", at + 1)) {
|
|
199
|
+
const empty = (at > 0 ? node.data[at - 1] : last) === "\n" ? charRect(node, at) : null;
|
|
200
|
+
if (empty) rects.push(empty);
|
|
201
|
+
}
|
|
202
|
+
if (node.length > 0) last = node.data.at(-1);
|
|
203
|
+
if (!node.data.trim()) continue;
|
|
204
|
+
range.selectNodeContents(node);
|
|
205
|
+
rects.push(...range.getClientRects());
|
|
206
|
+
}
|
|
207
|
+
if (closed) host.querySelectorAll(".doc-code-content").forEach((line) => { if (line.textContent === "") rects.push(...line.getClientRects()); });
|
|
208
|
+
host.querySelectorAll("[data-ge-atom]").forEach((chip) => { if (own(chip)) rects.push(...chip.getClientRects()); });
|
|
209
|
+
return rects.filter((rect) => rect.height >= 4);
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
// The box of the character at `at` in a text node, or null.
|
|
213
|
+
function charRect(node, at) {
|
|
214
|
+
const probe = document.createRange();
|
|
215
|
+
probe.setStart(node, at);
|
|
216
|
+
probe.setEnd(node, at + 1);
|
|
217
|
+
return probe.getClientRects()[0] ?? null;
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
// A block's box without the blocks a list item holds (its text line, for moving between lines).
|
|
221
|
+
export function ownRect(host) {
|
|
222
|
+
const rect = host.getBoundingClientRect();
|
|
223
|
+
const list = nestedBlocks(host)[0];
|
|
224
|
+
if (!list) return rect;
|
|
225
|
+
const bottom = Math.max(rect.top, list.getBoundingClientRect().top);
|
|
226
|
+
return { left: rect.left, right: rect.right, top: rect.top, bottom, width: rect.width, height: bottom - rect.top };
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
// The caret's box. A caret between elements (or in an empty block) has none of its own, so the
|
|
230
|
+
// end of the node before it (or the start of the node after it) is measured instead. `drawn`: the
|
|
231
|
+
// range is the selection's, measured where the browser draws its caret at a wrapped line's end
|
|
232
|
+
// (atLineEnd, for the arrow keys: it touches the selection, so never from a selectionchange).
|
|
233
|
+
export function caretRect(range, drawn = false) {
|
|
234
|
+
const { startContainer: node, startOffset: offset } = range;
|
|
235
|
+
if (node.nodeType === 3) return textRect(node, offset, drawn);
|
|
236
|
+
const before = node.childNodes[offset - 1];
|
|
237
|
+
const after = node.childNodes[offset];
|
|
238
|
+
return (before && edgeRect(before, true)) ?? (after && edgeRect(after, false)) ?? node.getBoundingClientRect();
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
function edgeRect(node, end) {
|
|
242
|
+
if (node.nodeType === 3) return textRect(node, end ? node.length : 0);
|
|
243
|
+
if (node.nodeType !== 1) return null;
|
|
244
|
+
const rects = node.getClientRects();
|
|
245
|
+
return rects.length > 0 ? rects[end ? rects.length - 1 : 0] : null;
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
// A caret's place in text, as notion-lite's caretRect measures it: the left edge of the character
|
|
249
|
+
// after it (a collapsed range measures the end of the line before at a line wrapped there, wherever
|
|
250
|
+
// the caret stands), at the end of the text the right edge of the character before. Where the
|
|
251
|
+
// browser wrapped a line, the end of the one and the start of the next are one place: the caret is
|
|
252
|
+
// taken at the next line's start (where a range selected stands), or where the browser draws it
|
|
253
|
+
// (`drawn`: atLineEnd). In preformatted text (a code block's) a line break is measured itself: before
|
|
254
|
+
// one, its own box, at the end of the line it ends (an empty line's too); right after one, the start
|
|
255
|
+
// of the next line.
|
|
256
|
+
function textRect(node, offset, drawn = false) {
|
|
257
|
+
const pre = preformatted(node);
|
|
258
|
+
if (pre && offset > 0 && node.data[offset - 1] === "\n") return afterBreak(node, offset);
|
|
259
|
+
const wrap = wrapAt(node, offset, pre);
|
|
260
|
+
if (wrap) return drawn && atLineEnd(node, offset) ? caretBox(wrap.before.right, wrap.before) : caretBox(wrap.after.left, wrap.after);
|
|
261
|
+
const after = offset < node.length ? charRect(node, offset) : null;
|
|
262
|
+
if (after) return caretBox(after.left, after);
|
|
263
|
+
const before = offset > 0 ? charRect(node, offset - 1) : null;
|
|
264
|
+
if (before) return caretBox(before.right, before);
|
|
265
|
+
const probe = document.createRange();
|
|
266
|
+
probe.setStart(node, offset);
|
|
267
|
+
probe.collapse(true);
|
|
268
|
+
return probe.getClientRects()[0] ?? null;
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
// The boxes of the characters on both sides of a place in text where the browser wrapped a line (the
|
|
272
|
+
// one before on a line above the one after's: between two Chinese characters, after a space, inside
|
|
273
|
+
// a long word), or null; never at a line break of preformatted text.
|
|
274
|
+
function wrapAt(node, offset, pre = preformatted(node)) {
|
|
275
|
+
if (offset === 0 || offset >= node.length || (pre && (node.data[offset - 1] === "\n" || node.data[offset] === "\n"))) return null;
|
|
276
|
+
const before = charRect(node, offset - 1);
|
|
277
|
+
const after = charRect(node, offset);
|
|
278
|
+
return before && after && after.top >= (before.top + before.bottom) / 2 ? { before, after } : null;
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
// Whether the caret at a wrapped line's end (wrapAt) stands at the end of the line before rather than
|
|
282
|
+
// at the start of the next. A range does not tell (the browser's affinity: End, or a click past the
|
|
283
|
+
// line's end, puts the caret at the end; a click at the next line's start, Home, the keys and a range
|
|
284
|
+
// selected, at the start), the selection does: moved to the start of its line, it stays where it is
|
|
285
|
+
// only at that line's start, and from the end it goes back as End takes it there. (Stretched to its
|
|
286
|
+
// line's end instead, a caret at the end is left at the next line's start.)
|
|
287
|
+
function atLineEnd(node, offset) {
|
|
288
|
+
const selection = getSelection();
|
|
289
|
+
if (!selection.modify || !selection.isCollapsed || selection.anchorNode !== node || selection.anchorOffset !== offset) return false;
|
|
290
|
+
selection.modify("move", "backward", "lineboundary");
|
|
291
|
+
if (selection.anchorNode === node && selection.anchorOffset === offset) return false;
|
|
292
|
+
selection.modify("move", "forward", "lineboundary");
|
|
293
|
+
if (selection.anchorNode !== node || selection.anchorOffset !== offset) selection.collapse(node, offset);
|
|
294
|
+
return true;
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
/**
|
|
298
|
+
* Put the caret at `range`, a place found on the line at height y (the keys', a click's). Where the
|
|
299
|
+
* browser wrapped a line there (wrapAt) the place is also the next line's start, where a range
|
|
300
|
+
* selected stands: on the line before, its end is reached as the browser's End reaches it.
|
|
301
|
+
*/
|
|
302
|
+
export function selectAt(range, y) {
|
|
303
|
+
select(range);
|
|
304
|
+
const { startContainer: node, startOffset: offset } = range;
|
|
305
|
+
const wrap = node.nodeType === 3 ? wrapAt(node, offset) : null;
|
|
306
|
+
if (!wrap || y >= (wrap.before.bottom + wrap.after.top) / 2) return;
|
|
307
|
+
const selection = getSelection();
|
|
308
|
+
selection.modify?.("move", "backward", "character");
|
|
309
|
+
selection.modify?.("move", "forward", "lineboundary");
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
const caretBox = (x, line) => ({ left: x, right: x, top: line.top, bottom: line.bottom, width: 0, height: line.height });
|
|
313
|
+
|
|
314
|
+
// Right after a line break of preformatted text: the next character's place, or with none (an empty
|
|
315
|
+
// last line) the line below the break's, at the text's left.
|
|
316
|
+
function afterBreak(node, offset) {
|
|
317
|
+
const root = editable(node) ?? node.parentElement;
|
|
318
|
+
const walker = document.createTreeWalker(root, NodeFilter.SHOW_TEXT);
|
|
319
|
+
walker.currentNode = node;
|
|
320
|
+
for (let text = node, at = offset; text; text = walker.nextNode(), at = 0) {
|
|
321
|
+
const rect = at < text.length ? charRect(text, at) : null;
|
|
322
|
+
if (rect) return caretBox(rect.left, rect);
|
|
323
|
+
}
|
|
324
|
+
const rect = charRect(node, offset - 1);
|
|
325
|
+
if (!rect) return null;
|
|
326
|
+
const left = root.getBoundingClientRect().left;
|
|
327
|
+
return { left, right: left, top: rect.bottom, bottom: rect.bottom + rect.height, width: 0, height: rect.height };
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
// The lines of a block that lie below the caret (or above it): where the caret can still move to
|
|
331
|
+
// inside the block.
|
|
332
|
+
function linesBeyond(host, caret, down) {
|
|
333
|
+
const middle = (rect) => (rect.top + rect.bottom) / 2;
|
|
334
|
+
return lineRects(host).filter((rect) => (down ? middle(rect) > caret.bottom : middle(rect) < caret.top));
|
|
335
|
+
}
|
|
336
|
+
|
|
337
|
+
// The caret is on the first (or last) line when no line of the block lies above (or below) it.
|
|
338
|
+
function onEdgeLine(host, caret, down) {
|
|
339
|
+
return !caret || linesBeyond(host, caret, down).length === 0;
|
|
340
|
+
}
|
|
341
|
+
|
|
342
|
+
// The line a caret coming from above (or below) meets first: the top one of `lines` when moving down,
|
|
343
|
+
// the bottom one when moving up.
|
|
344
|
+
const entryLine = (lines, down) => lines.reduce((a, b) => ((down ? b.top < a.top : b.bottom > a.bottom) ? b : a));
|
|
345
|
+
|
|
346
|
+
// The caret place on `line` (a line box of the block's own text) at column x, held within the block;
|
|
347
|
+
// null when the browser puts it outside the block or in a formula, where nothing can be typed.
|
|
348
|
+
function placeOnLine(host, line, x) {
|
|
349
|
+
const { left, right } = ownRect(host);
|
|
350
|
+
const range = onLine(host, { left, right, top: line.top, bottom: line.bottom }, x);
|
|
351
|
+
const node = range && (range.startContainer.nodeType === 1 ? range.startContainer : range.startContainer.parentElement);
|
|
352
|
+
return node && !node.closest("[data-ge-atom]") ? range : null;
|
|
353
|
+
}
|
|
354
|
+
|
|
355
|
+
export function pointRange(x, y) {
|
|
356
|
+
if (document.caretPositionFromPoint) {
|
|
357
|
+
const position = document.caretPositionFromPoint(x, y);
|
|
358
|
+
if (!position) return null;
|
|
359
|
+
const { offsetNode: node, offset } = position;
|
|
360
|
+
if (offset > (node.nodeType === 1 ? node.childNodes.length : node.length)) return null; // on a field holding words, a place in its value, which is no node's
|
|
361
|
+
const range = document.createRange();
|
|
362
|
+
range.setStart(node, offset);
|
|
363
|
+
return range;
|
|
364
|
+
}
|
|
365
|
+
return document.caretRangeFromPoint?.(x, y) ?? null;
|
|
366
|
+
}
|
|
367
|
+
|
|
368
|
+
/**
|
|
369
|
+
* Where a drag from `from` ([node, offset]) reaches with the pointer at (x, y), as [node, offset], or
|
|
370
|
+
* null. On a chip of the text, whose whole it takes as one character, it is the chip's far side from
|
|
371
|
+
* `from`: the browser's own place there comes and goes as the pointer passes the chip's pieces. Beside a
|
|
372
|
+
* chip whose text the browser's place is in (a line ending in it), it is the side the pointer is on.
|
|
373
|
+
*/
|
|
374
|
+
export function dragPlace(from, x, y) {
|
|
375
|
+
const at = pointRange(x, y);
|
|
376
|
+
const atom = atomOf(document.elementFromPoint(x, y)) ?? atomOf(at?.startContainer);
|
|
377
|
+
if (!atom) return at && [at.startContainer, at.startOffset];
|
|
378
|
+
const { left, right } = atom.getBoundingClientRect();
|
|
379
|
+
const start = document.createRange();
|
|
380
|
+
start.setStart(...from);
|
|
381
|
+
const after = x < left ? false : x > right ? true : start.comparePoint(atom, 0) >= 0;
|
|
382
|
+
return [atom.parentNode, [...atom.parentNode.childNodes].indexOf(atom) + (after ? 1 : 0)];
|
|
383
|
+
}
|
|
384
|
+
|
|
385
|
+
/**
|
|
386
|
+
* A press whose caret the editor placed itself (its mousedown cancelled, so the browser selects
|
|
387
|
+
* nothing as the pointer moves): dragging from it still selects the block's text, from that place
|
|
388
|
+
* to the pointer, until the button is let go. Past the block, text-select/ takes the selection over.
|
|
389
|
+
*/
|
|
390
|
+
export function followPress(host, anchor) {
|
|
391
|
+
const from = [anchor.startContainer, anchor.startOffset];
|
|
392
|
+
const move = (event) => {
|
|
393
|
+
if (!(event.buttons & 1)) return stop();
|
|
394
|
+
const to = from[0].isConnected ? dragPlace(from, event.clientX, event.clientY) : null;
|
|
395
|
+
if (to && editable(to[0]) === host) getSelection().setBaseAndExtent(...from, ...to);
|
|
396
|
+
};
|
|
397
|
+
const stop = () => {
|
|
398
|
+
removeEventListener("pointermove", move, true);
|
|
399
|
+
removeEventListener("pointerup", stop, true);
|
|
400
|
+
};
|
|
401
|
+
addEventListener("pointermove", move, true);
|
|
402
|
+
addEventListener("pointerup", stop, true);
|
|
403
|
+
}
|
|
404
|
+
|
|
405
|
+
/**
|
|
406
|
+
* Where a press on the text of a block holding chips of the text goes, for the editor to take its drag
|
|
407
|
+
* over (followPress: whole chips, where the browser's selection comes and goes as the pointer passes
|
|
408
|
+
* their pieces): the browser's place, beside a chip when that is in one; null in any other block, or on
|
|
409
|
+
* a chip, which a press puts no caret by.
|
|
410
|
+
*/
|
|
411
|
+
export function chipsPress(host, x, y) {
|
|
412
|
+
if (!host.querySelector("[data-ge-atom]") || atomOf(document.elementFromPoint(x, y))) return null;
|
|
413
|
+
const at = pointRange(x, y);
|
|
414
|
+
const atom = at && atomOf(at.startContainer);
|
|
415
|
+
if (atom) besideAtom(at, atom, x > atom.getBoundingClientRect().left);
|
|
416
|
+
return at && editable(at.startContainer) === host ? at : null;
|
|
417
|
+
}
|
|
418
|
+
|
|
419
|
+
// A place in a chip's own text taken right after the chip, or right before it.
|
|
420
|
+
function besideAtom(range, atom, after) {
|
|
421
|
+
if (after) range.setStartAfter(atom);
|
|
422
|
+
else range.setStartBefore(atom);
|
|
423
|
+
range.collapse(true);
|
|
424
|
+
}
|
|
425
|
+
|
|
426
|
+
/**
|
|
427
|
+
* A press beside a line of a block's own text, on the block's empty space (right of a line that
|
|
428
|
+
* ends early, say): the caret goes where that line is nearest the press, as the browser puts it.
|
|
429
|
+
* Returns that place when the browser would put the caret elsewhere, else null (on the text, not
|
|
430
|
+
* at a line's height, or where the browser gets it right). Chrome does, after a list item's text
|
|
431
|
+
* followed by its lists (not editable): it puts the caret at the start of the line.
|
|
432
|
+
*/
|
|
433
|
+
export function besideLine(host, x, y) {
|
|
434
|
+
const row = rowAt(host, y);
|
|
435
|
+
if (!row || (x >= row.left && x <= row.right)) return null;
|
|
436
|
+
const nearest = onLine(host, row, x);
|
|
437
|
+
const own = pointRange(x, y);
|
|
438
|
+
if (!nearest || (own && own.startContainer === nearest.startContainer && own.startOffset === nearest.startOffset)) return null;
|
|
439
|
+
// Beside a chip the browser's nearest place is in its own text: the place beside it.
|
|
440
|
+
const atom = atomOf(nearest.startContainer);
|
|
441
|
+
if (atom) besideAtom(nearest, atom, x > row.left);
|
|
442
|
+
return nearest;
|
|
443
|
+
}
|
|
444
|
+
|
|
445
|
+
/** The place on the line of a block's own text nearest to (x, y): that line's, or the nearest line's. */
|
|
446
|
+
export function nearestOnLine(host, x, y) {
|
|
447
|
+
const row = rowAt(host, y, true);
|
|
448
|
+
return row && onLine(host, row, x);
|
|
449
|
+
}
|
|
450
|
+
|
|
451
|
+
// The line of a block's own text at height y ({ left, right, top, bottom } over its pieces): the
|
|
452
|
+
// one at that height, or with `near`, else the nearest one.
|
|
453
|
+
function rowAt(host, y, near = false) {
|
|
454
|
+
const lines = lineRects(host);
|
|
455
|
+
const gap = (rect) => Math.max(rect.top - y, y - rect.bottom, 0);
|
|
456
|
+
const line = lines.find((rect) => gap(rect) === 0) ?? (near && lines.length > 0 ? lines.reduce((a, b) => (gap(b) < gap(a) ? b : a)) : null);
|
|
457
|
+
if (!line) return null;
|
|
458
|
+
const row = lines.filter((rect) => rect.top < line.bottom && rect.bottom > line.top);
|
|
459
|
+
return { left: Math.min(...row.map((rect) => rect.left)), right: Math.max(...row.map((rect) => rect.right)), top: line.top, bottom: line.bottom };
|
|
460
|
+
}
|
|
461
|
+
|
|
462
|
+
// The caret place on a line nearest to x (the point taken onto the line, where the browser finds it).
|
|
463
|
+
function onLine(host, row, x) {
|
|
464
|
+
const range = pointRange(within(x, row), (row.top + row.bottom) / 2);
|
|
465
|
+
return range && host.contains(range.startContainer) ? range : null;
|
|
466
|
+
}
|
|
467
|
+
|
|
468
|
+
// Put the caret into the target block at the same horizontal position, on its first line when
|
|
469
|
+
// moving down and its last line when moving up (notion-lite's moveInto). A code block not open yet
|
|
470
|
+
// opens (`open`) with the caret there.
|
|
471
|
+
function placeAt(target, x, down) {
|
|
472
|
+
target.scrollIntoView({ block: "nearest", inline: "nearest" });
|
|
473
|
+
const lines = lineRects(target);
|
|
474
|
+
const line = lines.length > 0 ? entryLine(lines, down) : null;
|
|
475
|
+
if (closedCode(target)) return openCode(target, line, x);
|
|
476
|
+
const range = x === undefined || !line ? null : placeOnLine(target, line, x);
|
|
477
|
+
if (!range) return caretAt(target, down ? "start" : "end");
|
|
478
|
+
target.focus({ preventScroll: true });
|
|
479
|
+
range.collapse(true);
|
|
480
|
+
selectAt(range, (line.top + line.bottom) / 2);
|
|
481
|
+
}
|
|
482
|
+
|
|
483
|
+
// A code block opened from the keys, as a press on it would (its component's `openAt`), the caret at
|
|
484
|
+
// column x on `line` (a line box of its code), held within that line's row (x Infinity: the row's
|
|
485
|
+
// end); at the code's start with no line.
|
|
486
|
+
function openCode(pre, line, x) {
|
|
487
|
+
const open = (at, point) => pageAt(at)?.openAt?.(at, point);
|
|
488
|
+
if (!line) return void open(pre, null);
|
|
489
|
+
const row = lineRects(pre).filter((rect) => rect.top < line.bottom && rect.bottom > line.top);
|
|
490
|
+
const left = Math.min(...row.map((rect) => rect.left));
|
|
491
|
+
const right = Math.max(...row.map((rect) => rect.right));
|
|
492
|
+
open(pre, { x: within(x, { left, right }), y: (line.top + line.bottom) / 2 });
|
|
493
|
+
}
|
|
494
|
+
|
|
495
|
+
// Column x held inside a row's ends (just inside, where the browser finds the place there); the
|
|
496
|
+
// row's start for an empty line (a box of no width).
|
|
497
|
+
const within = (x, { left, right }) => (right - left > 2 ? Math.min(Math.max(x, left + 1), right - 1) : left);
|
|
498
|
+
|
|
499
|
+
// Show a line the caret was put on without the browser's help (it scrolls only for its own moves):
|
|
500
|
+
// in the page, or in an open modal dialog's content, which scrolls by itself. The room kept clear at
|
|
501
|
+
// the edges is the one the browser keeps when it follows the caret there, the box's scroll-padding
|
|
502
|
+
// (a detail card's content keeps its padding, so a line of its last block takes it to its end), else
|
|
503
|
+
// `margin`.
|
|
504
|
+
export function reveal(host, line, margin = 24) {
|
|
505
|
+
const scroller = host.closest(DIALOG.openContent);
|
|
506
|
+
const view = scroller ? scroller.getBoundingClientRect() : { top: 0, bottom: innerHeight };
|
|
507
|
+
const style = getComputedStyle(scroller ?? document.documentElement);
|
|
508
|
+
const above = kept(style.scrollPaddingTop, margin);
|
|
509
|
+
const below = kept(style.scrollPaddingBottom, margin);
|
|
510
|
+
const exact = line.bottom > view.bottom - below ? line.bottom - view.bottom + below : line.top < view.top + above ? line.top - view.top - above : 0;
|
|
511
|
+
// Whole pixels, away from the line: a scroll by a fraction is rounded by the browser, and rounded
|
|
512
|
+
// down it left a line at the window's bottom a fraction of a pixel past it.
|
|
513
|
+
const delta = exact > 0 ? Math.ceil(exact) : Math.floor(exact);
|
|
514
|
+
if (!delta) return;
|
|
515
|
+
if (scroller) scroller.scrollTop += delta;
|
|
516
|
+
else scrollBy(0, delta);
|
|
517
|
+
}
|
|
518
|
+
|
|
519
|
+
const kept = (padding, margin) => (padding === "auto" ? margin : parseFloat(padding) || 0);
|
|
520
|
+
|
|
521
|
+
/**
|
|
522
|
+
* The caret shown after text went in, as the browser shows it after a key (reveal, with no room of
|
|
523
|
+
* the page's own): Chrome follows an input method's composition as it is typed but not the text that
|
|
524
|
+
* replaces it, so a phrase put in that wrapped onto a new line stood in a detail card's padding, or
|
|
525
|
+
* below the page's edge, until the next key. After a key the browser has shown it already: nothing moves.
|
|
526
|
+
*/
|
|
527
|
+
export function showCaret() {
|
|
528
|
+
const selection = getSelection();
|
|
529
|
+
const host = selection.rangeCount && selection.isCollapsed ? editable(selection.anchorNode) : null;
|
|
530
|
+
if (!host) return;
|
|
531
|
+
const rect = caretRect(selection.getRangeAt(0), true);
|
|
532
|
+
if (rect && (rect.top !== 0 || rect.bottom !== 0)) reveal(host, rect, 0);
|
|
533
|
+
showEnd();
|
|
534
|
+
}
|
|
535
|
+
|
|
536
|
+
/**
|
|
537
|
+
* A detail card's content taken to its very end when the caret is in its last block and that
|
|
538
|
+
* block's end is in view (the user's ask of 2026-10-23: the padding under the last block shown,
|
|
539
|
+
* never the block stopped against the card's bottom edge with more to scroll). A line of text gets
|
|
540
|
+
* there by the content's scroll-padding (dialog.css), the room the browser and reveal keep under the
|
|
541
|
+
* caret's line; a component holds room of its own under its last line (a code block's, a highlight
|
|
542
|
+
* block's or a callout's, a table's last row), and the content stopped that much short of its end.
|
|
543
|
+
* The caret's line stays in view. Run when the caret is put in a block (caretAt), after a key
|
|
544
|
+
* (followEnd) and after text put in (showCaret).
|
|
545
|
+
*/
|
|
546
|
+
export function showEnd() {
|
|
547
|
+
const selection = getSelection();
|
|
548
|
+
const host = selection.rangeCount ? editable(selection.focusNode) : null;
|
|
549
|
+
const scroller = host?.closest(DIALOG.openContent);
|
|
550
|
+
if (!scroller) return;
|
|
551
|
+
const rest = scroller.scrollHeight - scroller.clientHeight - scroller.scrollTop;
|
|
552
|
+
const last = [...scroller.children].findLast((node) => node.getClientRects().length > 0);
|
|
553
|
+
const view = scroller.getBoundingClientRect();
|
|
554
|
+
if (rest < 1 || !last?.contains(host) || last.getBoundingClientRect().bottom > view.bottom + 1) return;
|
|
555
|
+
const caret = document.createRange();
|
|
556
|
+
caret.setStart(selection.focusNode, selection.focusOffset);
|
|
557
|
+
const line = caretRect(caret, true);
|
|
558
|
+
const room = line.top || line.bottom ? line.top - view.top - kept(getComputedStyle(scroller).scrollPaddingTop, 0) : rest;
|
|
559
|
+
if (room > 0) scroller.scrollTop += Math.min(rest, room);
|
|
560
|
+
}
|
|
561
|
+
|
|
562
|
+
// After a key, once the browser has followed the caret (before the frame is drawn): showEnd.
|
|
563
|
+
let endFrame = 0;
|
|
564
|
+
|
|
565
|
+
/** A key pressed in an open detail card: its content taken to its end after it where showEnd says. */
|
|
566
|
+
export function followEnd() {
|
|
567
|
+
if (endFrame || !document.querySelector(DIALOG.open)) return;
|
|
568
|
+
endFrame = requestAnimationFrame(() => {
|
|
569
|
+
endFrame = 0;
|
|
570
|
+
showEnd();
|
|
571
|
+
});
|
|
572
|
+
}
|
|
573
|
+
|
|
574
|
+
// The next line of the same block at column x, for a caret that left its column on a short line
|
|
575
|
+
// (the browser would keep the caret's own column instead).
|
|
576
|
+
function lineStep(host, caret, x, down) {
|
|
577
|
+
const lines = linesBeyond(host, caret, down);
|
|
578
|
+
const line = lines.length > 0 ? entryLine(lines, down) : null;
|
|
579
|
+
const range = line && placeOnLine(host, line, x);
|
|
580
|
+
if (!range) return false;
|
|
581
|
+
range.collapse(true);
|
|
582
|
+
selectAt(range, (line.top + line.bottom) / 2);
|
|
583
|
+
reveal(host, line);
|
|
584
|
+
return true;
|
|
585
|
+
}
|
|
586
|
+
|
|
587
|
+
// The column a run of ↑/↓ presses keeps, as in any text editor: passing a short line (in a
|
|
588
|
+
// block, or a short block) does not pull the caret left for the lines after it. Any other key,
|
|
589
|
+
// a click or typing ends the run.
|
|
590
|
+
let goalX = null;
|
|
591
|
+
|
|
592
|
+
/** Any key but ↑/↓, a click or typing ends a run of ↑/↓ presses. */
|
|
593
|
+
export function endArrowRun() {
|
|
594
|
+
goalX = null;
|
|
595
|
+
}
|
|
596
|
+
|
|
597
|
+
/**
|
|
598
|
+
* ←/→ at a block's edge, ↑/↓ on its first or last line: the caret into the block before or after it
|
|
599
|
+
* in the page's order (places(), notion-lite's navigation.js handleArrow): ← at the end of the one
|
|
600
|
+
* before, → at the start of the one after, ↑ on the last line of the one before and ↓ on the first
|
|
601
|
+
* line of the one after, at the column a run of ↑/↓ began at. Blocks with no text (a divider, a
|
|
602
|
+
* picture, a card) are passed over; columns go one after the other. In a table ←/→ go cell by cell,
|
|
603
|
+
* row by row, and ↑/↓ to the cell above or below in the column (the user's rule, not notion-lite's:
|
|
604
|
+
* vertical()). Inside a block ↑/↓ are the browser's, but past a line shorter than that column
|
|
605
|
+
* (lineStep). Returns whether it moved the caret.
|
|
606
|
+
*/
|
|
607
|
+
export function arrow(host, key) {
|
|
608
|
+
const selection = getSelection();
|
|
609
|
+
if (!selection.rangeCount || !selection.isCollapsed) return false;
|
|
610
|
+
if (key === "ArrowLeft" || key === "ArrowRight") {
|
|
611
|
+
const forward = key === "ArrowRight";
|
|
612
|
+
if (!atEdge(host, forward)) return false;
|
|
613
|
+
const target = step(host, forward);
|
|
614
|
+
if (!target) return false;
|
|
615
|
+
if (!closedCode(target)) caretAt(target, forward ? "start" : "end");
|
|
616
|
+
else {
|
|
617
|
+
target.scrollIntoView({ block: "nearest", inline: "nearest" });
|
|
618
|
+
const lines = lineRects(target);
|
|
619
|
+
openCode(target, forward || lines.length === 0 ? null : entryLine(lines, false), Infinity);
|
|
620
|
+
}
|
|
621
|
+
return true;
|
|
622
|
+
}
|
|
623
|
+
const down = key === "ArrowDown";
|
|
624
|
+
const caret = caretRect(selection.getRangeAt(0), true);
|
|
625
|
+
const x = goalX ?? caret?.left ?? host.getBoundingClientRect().left;
|
|
626
|
+
goalX = x;
|
|
627
|
+
if (!onEdgeLine(host, caret, down)) return caret && Math.abs(caret.left - x) > 2 ? lineStep(host, caret, x, down) : false;
|
|
628
|
+
const target = vertical(host, x, down);
|
|
629
|
+
if (!target) return false;
|
|
630
|
+
placeAt(target, x, down, open);
|
|
631
|
+
return true;
|
|
632
|
+
}
|
|
633
|
+
|
|
634
|
+
// Where ↑/↓ take the caret from a block's first or last line. From a table's cell: the cell above or
|
|
635
|
+
// below it in the column at x (the table's slots, shared/table-slots.mjs: from a merged cell the row
|
|
636
|
+
// past all of its rows, among the cells under its columns the one at x; a merged cell once), and from
|
|
637
|
+
// the first row up (the last row down) the place before (after) the table. Into a table from the
|
|
638
|
+
// place before it, its first row's cell at x; from the place after it, its last row's. Elsewhere, or
|
|
639
|
+
// in a table whose cells tile no rectangle, the place before or after (step).
|
|
640
|
+
function vertical(host, x, down) {
|
|
641
|
+
const grid = gridOf(host);
|
|
642
|
+
const place = grid?.slots.places.get(host);
|
|
643
|
+
const inside = place ? inColumn(grid, down ? place.r + place.rows : place.r - 1, place, x, down) : null;
|
|
644
|
+
if (inside) return inside;
|
|
645
|
+
const target = step(place ? grid.table : host, down);
|
|
646
|
+
const entered = gridOf(target);
|
|
647
|
+
if (!entered || entered.table === grid?.table) return target;
|
|
648
|
+
return inColumn(entered, down ? 0 : entered.slots.matrix.length - 1, { c: 0, cols: entered.slots.columns }, x, down) ?? target;
|
|
649
|
+
}
|
|
650
|
+
|
|
651
|
+
// A table cell's table and slots ({ table, slots }), or null (not a cell, or cells that tile no rectangle).
|
|
652
|
+
function gridOf(node) {
|
|
653
|
+
if (node?.localName !== "td" && node?.localName !== "th") return null;
|
|
654
|
+
const table = node.closest("table");
|
|
655
|
+
const slots = table ? slotsOf([...table.rows]) : null;
|
|
656
|
+
return slots?.places.has(node) ? { table, slots } : null;
|
|
657
|
+
}
|
|
658
|
+
|
|
659
|
+
// The cell the caret goes into from row r on (down: r and the rows after it; up: r and the ones
|
|
660
|
+
// before), under the columns of `span` ({ c, cols }): in the first row with one the keys reach
|
|
661
|
+
// (places()), the one whose box holds x, else the nearest to x; null past the table's end.
|
|
662
|
+
function inColumn({ slots }, r, span, x, down) {
|
|
663
|
+
const reach = new Set(places());
|
|
664
|
+
const gap = (cell) => {
|
|
665
|
+
const { left, right } = cell.getBoundingClientRect();
|
|
666
|
+
return x < left ? left - x : x >= right ? x - right + 1 : 0;
|
|
667
|
+
};
|
|
668
|
+
for (; r >= 0 && r < slots.matrix.length; r += down ? 1 : -1) {
|
|
669
|
+
const cells = [...new Set(slots.matrix[r].slice(span.c, span.c + span.cols))].filter((cell) => reach.has(cell));
|
|
670
|
+
if (cells.length > 0) return cells.reduce((a, b) => (gap(b) < gap(a) ? b : a));
|
|
671
|
+
}
|
|
672
|
+
return null;
|
|
673
|
+
}
|
|
674
|
+
|
|
675
|
+
// The place before or after `host` (places()), or null; from a block the keys pass over (a formula
|
|
676
|
+
// block holding the caret), the nearest one on that side.
|
|
677
|
+
function step(host, forward) {
|
|
678
|
+
const list = places();
|
|
679
|
+
const index = list.indexOf(host);
|
|
680
|
+
if (index >= 0) return list[index + (forward ? 1 : -1)] ?? null;
|
|
681
|
+
return (forward ? list.find((node) => inOrder(host, node) < 0 && !host.contains(node)) : list.findLast((node) => inOrder(node, host) < 0 && !node.contains(host))) ?? null;
|
|
682
|
+
}
|