@morphemecms/cms 0.1.0 → 0.2.0-next-20261104150211
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/CHANGELOG.md +12 -0
- package/LICENSE +21 -21
- package/README.md +51 -51
- package/astro.mjs +162 -162
- package/bin/morpheme.mjs +38 -38
- package/client.d.ts +10 -10
- package/defaults/blockTexts.ts +33 -33
- package/defaults/collections.ts +774 -774
- package/defaults/colors.ts +125 -125
- package/defaults/company.ts +20 -20
- package/defaults/editor.ts +178 -178
- package/defaults/internalLinks.ts +30 -30
- package/defaults/opens.ts +18 -18
- package/defaults/popup.tsx +93 -93
- package/defaults/privacy.ts +79 -79
- package/defaults/rules.ts +450 -450
- package/defaults/schema.ts +16 -16
- package/defaults/sitedata.ts +129 -129
- package/defaults/standard.ts +106 -106
- package/defaults/standardPages.ts +87 -87
- package/defaults/texts.ts +481 -481
- package/demo/README.md +26 -26
- package/demo/src/content/blog/build-a-page-from-blocks.md +19 -19
- package/demo/src/content/blog/colors-everyone-can-read.md +19 -19
- package/demo/src/content/blog/edit-your-website-from-your-phone.md +21 -21
- package/demo/src/content/blog/every-save-is-a-version.md +21 -21
- package/demo/src/content/blog/schedule-a-post.md +17 -17
- package/demo/src/content/blog/secure-from-day-one.md +17 -17
- package/demo/src/content/blog/seo-without-the-guesswork.md +23 -23
- package/demo/src/content/blog/switch-themes-without-losing-anything.md +23 -23
- package/demo/src/content/blog/the-app-store.md +21 -21
- package/demo/src/content/pages/about.md +22 -22
- package/demo/src/content/pages/app-store.md +30 -30
- package/demo/src/content/pages/blocks.md +98 -98
- package/demo/src/content/pages/blog-page.md +11 -11
- package/demo/src/content/pages/contact.md +16 -16
- package/demo/src/content/pages/get-started.md +20 -20
- package/demo/src/content/pages/home.md +26 -26
- package/demo/src/content/pages/page-not-found.md +11 -11
- package/demo/src/content/pages/privacy-policy.md +24 -24
- package/demo/src/data/blocks.json +25 -25
- package/demo/src/data/booking.json +6 -6
- package/demo/src/data/categories/apps.json +6 -6
- package/demo/src/data/categories/design.json +6 -6
- package/demo/src/data/categories/editing.json +6 -6
- package/demo/src/data/categories/security.json +6 -6
- package/demo/src/data/categories/seo.json +6 -6
- package/demo/src/data/colors.json +75 -75
- package/demo/src/data/contact.json +8 -8
- package/demo/src/data/cookies.json +21 -21
- package/demo/src/data/footer.json +27 -27
- package/demo/src/data/menu.json +35 -35
- package/demo/src/data/mobile-menu.json +25 -25
- package/demo/src/data/popups/booking-bar.json +13 -13
- package/demo/src/data/popups/try-the-editor.json +16 -16
- package/demo/src/data/standard-pages.json +8 -8
- package/demo/src/data/testimonials/sample-bakery.json +10 -10
- package/demo/src/data/testimonials/sample-clinic.json +10 -10
- package/demo/src/data/testimonials/sample-studio.json +10 -10
- package/demo/src/site/colors.ts +11 -11
- package/demo/src/site/config.ts +19 -19
- package/icons/lucide/LICENSE +43 -43
- package/icons/lucide/address-book.svg +1 -1
- package/icons/lucide/app-window.svg +1 -1
- package/icons/lucide/arrow-counter-clockwise.svg +1 -1
- package/icons/lucide/arrow-down.svg +1 -1
- package/icons/lucide/arrow-left.svg +1 -1
- package/icons/lucide/arrow-right.svg +1 -1
- package/icons/lucide/arrow-square-out.svg +1 -1
- package/icons/lucide/arrow-u-up-left.svg +1 -1
- package/icons/lucide/arrow-u-up-right.svg +1 -1
- package/icons/lucide/arrow-up-right.svg +1 -1
- package/icons/lucide/arrow-up.svg +1 -1
- package/icons/lucide/arrows-down-up.svg +1 -1
- package/icons/lucide/arrows-in-line-horizontal.svg +1 -1
- package/icons/lucide/arrows-out-line-horizontal.svg +1 -1
- package/icons/lucide/article.svg +1 -1
- package/icons/lucide/bank.svg +1 -1
- package/icons/lucide/bell.svg +1 -1
- package/icons/lucide/bicycle.svg +1 -1
- package/icons/lucide/binoculars.svg +1 -1
- package/icons/lucide/book-open-text.svg +1 -1
- package/icons/lucide/book-open.svg +1 -1
- package/icons/lucide/browser.svg +1 -1
- package/icons/lucide/buildings.svg +1 -1
- package/icons/lucide/bus.svg +1 -1
- package/icons/lucide/calendar-blank.svg +1 -1
- package/icons/lucide/calendar-check.svg +1 -1
- package/icons/lucide/car.svg +1 -1
- package/icons/lucide/cards.svg +1 -1
- package/icons/lucide/caret-down.svg +1 -1
- package/icons/lucide/caret-left.svg +1 -1
- package/icons/lucide/caret-right.svg +1 -1
- package/icons/lucide/caret-up.svg +1 -1
- package/icons/lucide/certificate.svg +1 -1
- package/icons/lucide/chart-line-up.svg +1 -1
- package/icons/lucide/chats.svg +1 -1
- package/icons/lucide/check-circle.svg +1 -1
- package/icons/lucide/check.svg +1 -1
- package/icons/lucide/circle-half.svg +1 -1
- package/icons/lucide/circle.svg +1 -1
- package/icons/lucide/clock-counter-clockwise.svg +1 -1
- package/icons/lucide/clock.svg +1 -1
- package/icons/lucide/code.svg +1 -1
- package/icons/lucide/coffee.svg +1 -1
- package/icons/lucide/columns.svg +1 -1
- package/icons/lucide/cookie.svg +1 -1
- package/icons/lucide/copy.svg +1 -1
- package/icons/lucide/credit-card.svg +1 -1
- package/icons/lucide/currency-circle-dollar.svg +1 -1
- package/icons/lucide/cursor-click.svg +1 -1
- package/icons/lucide/database.svg +1 -1
- package/icons/lucide/desktop.svg +1 -1
- package/icons/lucide/device-mobile.svg +1 -1
- package/icons/lucide/door-open.svg +1 -1
- package/icons/lucide/download-simple.svg +1 -1
- package/icons/lucide/envelope-simple.svg +1 -1
- package/icons/lucide/eye-slash.svg +1 -1
- package/icons/lucide/eye.svg +1 -1
- package/icons/lucide/file-pdf.svg +1 -1
- package/icons/lucide/file-text.svg +1 -1
- package/icons/lucide/file-video.svg +1 -1
- package/icons/lucide/file-zip.svg +1 -1
- package/icons/lucide/flower-lotus.svg +1 -1
- package/icons/lucide/folder-simple.svg +1 -1
- package/icons/lucide/funnel.svg +1 -1
- package/icons/lucide/gauge.svg +1 -1
- package/icons/lucide/gear.svg +1 -1
- package/icons/lucide/github-logo.svg +1 -1
- package/icons/lucide/globe.svg +1 -1
- package/icons/lucide/google-logo.svg +1 -1
- package/icons/lucide/graduation-cap.svg +1 -1
- package/icons/lucide/hammer.svg +1 -1
- package/icons/lucide/hand-heart.svg +1 -1
- package/icons/lucide/handshake.svg +1 -1
- package/icons/lucide/hard-drives.svg +1 -1
- package/icons/lucide/heart.svg +1 -1
- package/icons/lucide/house.svg +1 -1
- package/icons/lucide/image-square.svg +1 -1
- package/icons/lucide/image.svg +1 -1
- package/icons/lucide/info.svg +1 -1
- package/icons/lucide/keyboard.svg +1 -1
- package/icons/lucide/leaf.svg +1 -1
- package/icons/lucide/lifebuoy.svg +1 -1
- package/icons/lucide/lightbulb.svg +1 -1
- package/icons/lucide/link-break.svg +1 -1
- package/icons/lucide/link-simple.svg +1 -1
- package/icons/lucide/list-bullets.svg +1 -1
- package/icons/lucide/list-checks.svg +1 -1
- package/icons/lucide/list-numbers.svg +1 -1
- package/icons/lucide/list.svg +1 -1
- package/icons/lucide/lock-simple-open.svg +1 -1
- package/icons/lucide/lock-simple.svg +1 -1
- package/icons/lucide/magnifying-glass.svg +1 -1
- package/icons/lucide/map-pin.svg +1 -1
- package/icons/lucide/map-trifold.svg +1 -1
- package/icons/lucide/medal.svg +1 -1
- package/icons/lucide/megaphone.svg +1 -1
- package/icons/lucide/minus.svg +1 -1
- package/icons/lucide/moon.svg +1 -1
- package/icons/lucide/newspaper.svg +1 -1
- package/icons/lucide/pack.json +23 -23
- package/icons/lucide/paint-brush-broad.svg +1 -1
- package/icons/lucide/palette.svg +1 -1
- package/icons/lucide/paper-plane-tilt.svg +1 -1
- package/icons/lucide/pencil-simple.svg +1 -1
- package/icons/lucide/phone.svg +1 -1
- package/icons/lucide/play-fill.svg +1 -1
- package/icons/lucide/plus.svg +1 -1
- package/icons/lucide/prohibit.svg +1 -1
- package/icons/lucide/puzzle-piece.svg +1 -1
- package/icons/lucide/question.svg +1 -1
- package/icons/lucide/quotes.svg +1 -1
- package/icons/lucide/rows.svg +1 -1
- package/icons/lucide/ruler.svg +1 -1
- package/icons/lucide/scan.svg +1 -1
- package/icons/lucide/shapes.svg +1 -1
- package/icons/lucide/share-network.svg +1 -1
- package/icons/lucide/shield-check.svg +1 -1
- package/icons/lucide/sidebar-simple.svg +1 -1
- package/icons/lucide/sign-out.svg +1 -1
- package/icons/lucide/signpost.svg +1 -1
- package/icons/lucide/sliders-horizontal.svg +1 -1
- package/icons/lucide/smiley.svg +1 -1
- package/icons/lucide/sparkle.svg +1 -1
- package/icons/lucide/square-half-bottom.svg +1 -1
- package/icons/lucide/square.svg +1 -1
- package/icons/lucide/squares-four.svg +1 -1
- package/icons/lucide/sticker.svg +1 -1
- package/icons/lucide/storefront.svg +1 -1
- package/icons/lucide/sun.svg +1 -1
- package/icons/lucide/swatches.svg +1 -1
- package/icons/lucide/tag.svg +1 -1
- package/icons/lucide/text-aa.svg +1 -1
- package/icons/lucide/text-align-left.svg +1 -1
- package/icons/lucide/text-b.svg +1 -1
- package/icons/lucide/text-h-one.svg +1 -1
- package/icons/lucide/text-h-three.svg +1 -1
- package/icons/lucide/text-h-two.svg +1 -1
- package/icons/lucide/text-italic.svg +1 -1
- package/icons/lucide/text-t.svg +1 -1
- package/icons/lucide/ticket.svg +1 -1
- package/icons/lucide/toggle-right.svg +1 -1
- package/icons/lucide/train.svg +1 -1
- package/icons/lucide/trash.svg +1 -1
- package/icons/lucide/upload-simple.svg +1 -1
- package/icons/lucide/user-circle.svg +1 -1
- package/icons/lucide/user.svg +1 -1
- package/icons/lucide/users-three.svg +1 -1
- package/icons/lucide/users.svg +1 -1
- package/icons/lucide/video-camera.svg +1 -1
- package/icons/lucide/warning-circle.svg +1 -1
- package/icons/lucide/warning.svg +1 -1
- package/icons/lucide/wave-sine.svg +1 -1
- package/icons/lucide/wheelchair.svg +1 -1
- package/icons/lucide/wrench.svg +1 -1
- package/icons/lucide/x.svg +1 -1
- package/icons/material-symbols/LICENSE +201 -201
- package/icons/material-symbols/address-book.svg +1 -1
- package/icons/material-symbols/app-window.svg +1 -1
- package/icons/material-symbols/arrow-counter-clockwise.svg +1 -1
- package/icons/material-symbols/arrow-down.svg +1 -1
- package/icons/material-symbols/arrow-left.svg +1 -1
- package/icons/material-symbols/arrow-right.svg +1 -1
- package/icons/material-symbols/arrow-square-out.svg +1 -1
- package/icons/material-symbols/arrow-u-up-left.svg +1 -1
- package/icons/material-symbols/arrow-u-up-right.svg +1 -1
- package/icons/material-symbols/arrow-up-right.svg +1 -1
- package/icons/material-symbols/arrow-up.svg +1 -1
- package/icons/material-symbols/arrows-down-up.svg +1 -1
- package/icons/material-symbols/arrows-in-line-horizontal.svg +1 -1
- package/icons/material-symbols/arrows-out-line-horizontal.svg +1 -1
- package/icons/material-symbols/article.svg +1 -1
- package/icons/material-symbols/bank.svg +1 -1
- package/icons/material-symbols/bell.svg +1 -1
- package/icons/material-symbols/bicycle.svg +1 -1
- package/icons/material-symbols/binoculars.svg +1 -1
- package/icons/material-symbols/book-open-text.svg +1 -1
- package/icons/material-symbols/book-open.svg +1 -1
- package/icons/material-symbols/browser.svg +1 -1
- package/icons/material-symbols/buildings.svg +1 -1
- package/icons/material-symbols/bus.svg +1 -1
- package/icons/material-symbols/calendar-blank.svg +1 -1
- package/icons/material-symbols/calendar-check.svg +1 -1
- package/icons/material-symbols/car.svg +1 -1
- package/icons/material-symbols/cards.svg +1 -1
- package/icons/material-symbols/caret-down.svg +1 -1
- package/icons/material-symbols/caret-left.svg +1 -1
- package/icons/material-symbols/caret-right.svg +1 -1
- package/icons/material-symbols/caret-up.svg +1 -1
- package/icons/material-symbols/certificate.svg +1 -1
- package/icons/material-symbols/chart-line-up.svg +1 -1
- package/icons/material-symbols/chats.svg +1 -1
- package/icons/material-symbols/check-circle.svg +1 -1
- package/icons/material-symbols/check.svg +1 -1
- package/icons/material-symbols/circle-half.svg +1 -1
- package/icons/material-symbols/circle.svg +1 -1
- package/icons/material-symbols/clock-counter-clockwise.svg +1 -1
- package/icons/material-symbols/clock.svg +1 -1
- package/icons/material-symbols/code.svg +1 -1
- package/icons/material-symbols/coffee.svg +1 -1
- package/icons/material-symbols/columns.svg +1 -1
- package/icons/material-symbols/cookie.svg +1 -1
- package/icons/material-symbols/copy.svg +1 -1
- package/icons/material-symbols/credit-card.svg +1 -1
- package/icons/material-symbols/currency-circle-dollar.svg +1 -1
- package/icons/material-symbols/cursor-click.svg +1 -1
- package/icons/material-symbols/database.svg +1 -1
- package/icons/material-symbols/desktop.svg +1 -1
- package/icons/material-symbols/device-mobile.svg +1 -1
- package/icons/material-symbols/door-open.svg +1 -1
- package/icons/material-symbols/download-simple.svg +1 -1
- package/icons/material-symbols/envelope-simple.svg +1 -1
- package/icons/material-symbols/eye-slash.svg +1 -1
- package/icons/material-symbols/eye.svg +1 -1
- package/icons/material-symbols/file-pdf.svg +1 -1
- package/icons/material-symbols/file-text.svg +1 -1
- package/icons/material-symbols/file-video.svg +1 -1
- package/icons/material-symbols/file-zip.svg +1 -1
- package/icons/material-symbols/flower-lotus.svg +1 -1
- package/icons/material-symbols/folder-simple.svg +1 -1
- package/icons/material-symbols/funnel.svg +1 -1
- package/icons/material-symbols/gauge.svg +1 -1
- package/icons/material-symbols/gear.svg +1 -1
- package/icons/material-symbols/github-logo.svg +1 -1
- package/icons/material-symbols/globe.svg +1 -1
- package/icons/material-symbols/google-logo.svg +1 -1
- package/icons/material-symbols/graduation-cap.svg +1 -1
- package/icons/material-symbols/hammer.svg +1 -1
- package/icons/material-symbols/hand-heart.svg +1 -1
- package/icons/material-symbols/handshake.svg +1 -1
- package/icons/material-symbols/hard-drives.svg +1 -1
- package/icons/material-symbols/heart.svg +1 -1
- package/icons/material-symbols/house.svg +1 -1
- package/icons/material-symbols/image-square.svg +1 -1
- package/icons/material-symbols/image.svg +1 -1
- package/icons/material-symbols/info.svg +1 -1
- package/icons/material-symbols/keyboard.svg +1 -1
- package/icons/material-symbols/leaf.svg +1 -1
- package/icons/material-symbols/lifebuoy.svg +1 -1
- package/icons/material-symbols/lightbulb.svg +1 -1
- package/icons/material-symbols/link-break.svg +1 -1
- package/icons/material-symbols/link-simple.svg +1 -1
- package/icons/material-symbols/list-bullets.svg +1 -1
- package/icons/material-symbols/list-checks.svg +1 -1
- package/icons/material-symbols/list-numbers.svg +1 -1
- package/icons/material-symbols/list.svg +1 -1
- package/icons/material-symbols/lock-simple-open.svg +1 -1
- package/icons/material-symbols/lock-simple.svg +1 -1
- package/icons/material-symbols/magnifying-glass.svg +1 -1
- package/icons/material-symbols/map-pin.svg +1 -1
- package/icons/material-symbols/map-trifold.svg +1 -1
- package/icons/material-symbols/medal.svg +1 -1
- package/icons/material-symbols/megaphone.svg +1 -1
- package/icons/material-symbols/minus.svg +1 -1
- package/icons/material-symbols/moon.svg +1 -1
- package/icons/material-symbols/newspaper.svg +1 -1
- package/icons/material-symbols/pack.json +29 -29
- package/icons/material-symbols/paint-brush-broad.svg +1 -1
- package/icons/material-symbols/palette.svg +1 -1
- package/icons/material-symbols/paper-plane-tilt.svg +1 -1
- package/icons/material-symbols/pencil-simple.svg +1 -1
- package/icons/material-symbols/phone.svg +1 -1
- package/icons/material-symbols/play-fill.svg +1 -1
- package/icons/material-symbols/plus.svg +1 -1
- package/icons/material-symbols/prohibit.svg +1 -1
- package/icons/material-symbols/puzzle-piece.svg +1 -1
- package/icons/material-symbols/question.svg +1 -1
- package/icons/material-symbols/quotes.svg +1 -1
- package/icons/material-symbols/rows.svg +1 -1
- package/icons/material-symbols/ruler.svg +1 -1
- package/icons/material-symbols/scan.svg +1 -1
- package/icons/material-symbols/shapes.svg +1 -1
- package/icons/material-symbols/share-network.svg +1 -1
- package/icons/material-symbols/shield-check.svg +1 -1
- package/icons/material-symbols/sidebar-simple.svg +1 -1
- package/icons/material-symbols/sign-out.svg +1 -1
- package/icons/material-symbols/signpost.svg +1 -1
- package/icons/material-symbols/sliders-horizontal.svg +1 -1
- package/icons/material-symbols/smiley.svg +1 -1
- package/icons/material-symbols/sparkle.svg +1 -1
- package/icons/material-symbols/square-half-bottom.svg +1 -1
- package/icons/material-symbols/square.svg +1 -1
- package/icons/material-symbols/squares-four.svg +1 -1
- package/icons/material-symbols/sticker.svg +1 -1
- package/icons/material-symbols/storefront.svg +1 -1
- package/icons/material-symbols/sun.svg +1 -1
- package/icons/material-symbols/swatches.svg +1 -1
- package/icons/material-symbols/tag.svg +1 -1
- package/icons/material-symbols/text-aa.svg +1 -1
- package/icons/material-symbols/text-align-left.svg +1 -1
- package/icons/material-symbols/text-b.svg +1 -1
- package/icons/material-symbols/text-h-one.svg +1 -1
- package/icons/material-symbols/text-h-three.svg +1 -1
- package/icons/material-symbols/text-h-two.svg +1 -1
- package/icons/material-symbols/text-italic.svg +1 -1
- package/icons/material-symbols/text-t.svg +1 -1
- package/icons/material-symbols/ticket.svg +1 -1
- package/icons/material-symbols/toggle-right.svg +1 -1
- package/icons/material-symbols/train.svg +1 -1
- package/icons/material-symbols/trash.svg +1 -1
- package/icons/material-symbols/upload-simple.svg +1 -1
- package/icons/material-symbols/user-circle.svg +1 -1
- package/icons/material-symbols/user.svg +1 -1
- package/icons/material-symbols/users-three.svg +1 -1
- package/icons/material-symbols/users.svg +1 -1
- package/icons/material-symbols/video-camera.svg +1 -1
- package/icons/material-symbols/warning-circle.svg +1 -1
- package/icons/material-symbols/warning.svg +1 -1
- package/icons/material-symbols/wave-sine.svg +1 -1
- package/icons/material-symbols/wheelchair.svg +1 -1
- package/icons/material-symbols/wrench.svg +1 -1
- package/icons/material-symbols/x.svg +1 -1
- package/icons/phosphor/pack.json +8 -8
- package/lib/apps.mjs +142 -139
- package/lib/apps.test.d.mts +1 -0
- package/lib/apps.test.mjs +50 -0
- package/lib/blocks.mjs +90 -90
- package/lib/caseCollisions.d.mts +4 -0
- package/lib/caseCollisions.mjs +62 -0
- package/lib/caseCollisions.test.d.mts +1 -0
- package/lib/caseCollisions.test.mjs +74 -0
- package/lib/colors.ts +86 -86
- package/lib/contactBar.ts +18 -18
- package/lib/contracts.d.mts +15 -0
- package/lib/contracts.mjs +17 -0
- package/lib/cookieCategories.mjs +28 -28
- package/lib/crop.mjs +83 -83
- package/lib/csp.mjs +130 -130
- package/lib/cspSources.mjs +60 -60
- package/lib/dynamic-colors.ts +426 -426
- package/lib/git.mjs +64 -64
- package/lib/hooks.ts +51 -51
- package/lib/inline.ts +20 -20
- package/lib/license-texts/Apache-2.0.txt +190 -190
- package/lib/license-texts/BSD-2-Clause.txt +24 -24
- package/lib/license-texts/BSD-3-Clause.txt +28 -28
- package/lib/license-texts/ISC.txt +15 -15
- package/lib/license-texts/MIT.txt +21 -21
- package/lib/licenses.d.mts +1 -1
- package/lib/licenses.mjs +683 -683
- package/lib/markdown.ts +42 -42
- package/lib/motion-schemes.mjs +5 -5
- package/lib/motion.ts +131 -131
- package/lib/notice.mjs +34 -34
- package/lib/scheduled.mjs +37 -37
- package/lib/snackbar.ts +149 -149
- package/lib/status.mjs +18 -18
- package/lib/storeEntries.d.mts +18 -0
- package/lib/storeEntries.mjs +64 -0
- package/lib/storeEntries.test.d.mts +1 -0
- package/lib/storeEntries.test.mjs +71 -0
- package/lib/svg.mjs +231 -231
- package/lib/text-colors.mjs +43 -43
- package/lib/video-id.mjs +72 -72
- package/lib/video.mjs +91 -91
- package/package.json +136 -131
- package/pages/404.astro +10 -10
- package/pages/[...slug].astro +51 -51
- package/pages/_headers.txt +31 -31
- package/pages/blog/index.astro +10 -10
- package/pages/blog/kategori/[category].astro +18 -18
- package/pages/editor/code-images.json.js +25 -25
- package/pages/editor/index.astro +75 -75
- package/pages/editor/manifest.webmanifest.js +23 -23
- package/pages/editor/sw.js +33 -33
- package/pages/editor/sw.js.js +4 -4
- package/pages/editor/thumbnails.json.js +21 -21
- package/pages/editor/version.json.js +22 -22
- package/pages/headers.js +4 -4
- package/pages/index.astro +10 -10
- package/pages/ny.astro +6 -6
- package/pages/robots.txt.js +3 -3
- package/pages/rss.xml.js +20 -20
- package/scripts/app-screenshots.mjs +164 -164
- package/scripts/app-workers.mjs +6 -6
- package/scripts/bin.mjs +12 -12
- package/scripts/built-site.mjs +134 -99
- package/scripts/check-consent.mjs +113 -113
- package/scripts/check-content.mjs +151 -149
- package/scripts/check-demo.mjs +24 -24
- package/scripts/check-store.mjs +160 -0
- package/scripts/check-themes.mjs +45 -45
- package/scripts/check-worker.mjs +569 -569
- package/scripts/compare-html.mjs +81 -81
- package/scripts/declarations.mjs +10 -0
- package/scripts/declarations.test.mjs +32 -0
- package/scripts/demo-site.mjs +42 -42
- package/scripts/editor-icons.mjs +56 -56
- package/scripts/editor-roundtrip.mjs +134 -134
- package/scripts/editor-screens.mjs +101 -101
- package/scripts/git-env.mjs +9 -9
- package/scripts/icon-packs.mjs +151 -151
- package/scripts/link-counts.mjs +22 -22
- package/scripts/page-colors.mjs +42 -42
- package/scripts/releases.mjs +80 -80
- package/scripts/responsive-images.mjs +94 -94
- package/scripts/scheduled-list.mjs +15 -15
- package/scripts/theme-screenshots.mjs +88 -88
- package/scripts/types.mjs +17 -21
- package/scripts/video-thumbnails.mjs +89 -89
- package/scripts/worker-modules.mjs +34 -34
- package/site/appCookies.mjs +74 -74
- package/site/apps.ts +21 -21
- package/site/autolinks.mjs +200 -200
- package/site/blockScripts.ts +31 -31
- package/site/categories.ts +16 -16
- package/site/consent.ts +26 -26
- package/site/content.config.ts +84 -84
- package/site/content.ts +104 -104
- package/site/cookieList.ts +17 -17
- package/site/defineSite.d.mts +2 -14
- package/site/defineSite.mjs +131 -136
- package/site/directives/interact.mjs +31 -31
- package/site/editor-version.mjs +26 -26
- package/site/fill.ts +13 -13
- package/site/format.ts +11 -11
- package/site/home.ts +66 -66
- package/site/iconPacks.mjs +43 -43
- package/site/icons.mjs +605 -605
- package/site/images.mjs +157 -157
- package/site/motion.ts +13 -13
- package/site/noindex.mjs +21 -21
- package/site/pageColors.ts +110 -110
- package/site/popups.ts +98 -98
- package/site/schema.ts +189 -189
- package/site/sections.ts +3 -3
- package/site/seo.ts +28 -28
- package/site/site.ts +76 -76
- package/site/siteConfig.mjs +8 -8
- package/site/siteCsp.mjs +75 -75
- package/site/siteModules.mjs +27 -27
- package/site/standardPages.ts +59 -59
- package/site/storeTheme.d.mts +6 -0
- package/site/storeTheme.mjs +29 -0
- package/site/storeTheme.test.d.mts +1 -0
- package/site/storeTheme.test.mjs +53 -0
- package/site/testimonials.ts +48 -48
- package/site/text.ts +43 -43
- package/site/theme.mjs +483 -472
- package/site/tracking.client.ts +225 -225
- package/site/tracking.ts +9 -9
- package/src/ActionParts.tsx +205 -205
- package/src/Advanced.tsx +152 -152
- package/src/App.tsx +901 -904
- package/src/AppList.tsx +1362 -1345
- package/src/BlockDialog.tsx +360 -360
- package/src/BlockParts.tsx +652 -652
- package/src/BlockSettings.tsx +533 -533
- package/src/BrandForm.tsx +164 -164
- package/src/Colors.tsx +476 -476
- package/src/CommunicationParts.tsx +199 -199
- package/src/CompanyForm.tsx +209 -209
- package/src/Consents.tsx +175 -175
- package/src/ContainmentParts.tsx +185 -185
- package/src/Crop.tsx +152 -152
- package/src/DataForm.tsx +434 -434
- package/src/Deleted.tsx +177 -177
- package/src/EntryForm.tsx +740 -740
- package/src/FileView.tsx +30 -30
- package/src/FormFrame.tsx +237 -237
- package/src/Keywords.tsx +225 -225
- package/src/Library.tsx +1563 -1563
- package/src/Licenses.tsx +336 -336
- package/src/LinkSheet.tsx +138 -138
- package/src/MarkdownEditor.tsx +1075 -1075
- package/src/Media.tsx +677 -677
- package/src/NavigationParts.tsx +350 -350
- package/src/NavigationRestParts.tsx +247 -247
- package/src/Notifications.tsx +59 -59
- package/src/PagePicker.tsx +136 -136
- package/src/Parts.tsx +991 -991
- package/src/PartsShown.tsx +168 -168
- package/src/PickerParts.tsx +183 -183
- package/src/Redirects.tsx +450 -450
- package/src/Screen.tsx +184 -184
- package/src/SectionsField.tsx +65 -65
- package/src/SelectionParts.tsx +134 -134
- package/src/SeoScores.tsx +184 -184
- package/src/Sheet.tsx +35 -35
- package/src/ThemeStore.tsx +376 -376
- package/src/Tokens.tsx +346 -346
- package/src/Versions.tsx +214 -214
- package/src/addresses.ts +75 -75
- package/src/allIcons.ts +7 -7
- package/src/appFiles.ts +29 -29
- package/src/apps.ts +281 -281
- package/src/ask.tsx +123 -123
- package/src/blocks.ts +251 -251
- package/src/brand.ts +153 -153
- package/src/cache.ts +42 -42
- package/src/check.ts +285 -285
- package/src/checkSite.ts +256 -256
- package/src/{consents.ts → consentData.ts} +26 -26
- package/src/cookieList.ts +70 -70
- package/src/countries.ts +59 -59
- package/src/deploy.ts +155 -155
- package/src/editor.css +602 -602
- package/src/examples.ts +85 -85
- package/src/fields.tsx +942 -942
- package/src/frontmatter.mjs +42 -42
- package/src/github.ts +376 -376
- package/src/i18n/da-DK/advanced.ts +28 -28
- package/src/i18n/da-DK/app.ts +71 -71
- package/src/i18n/da-DK/apps.ts +90 -90
- package/src/i18n/da-DK/blockSettings.ts +38 -38
- package/src/i18n/da-DK/blocks.ts +408 -408
- package/src/i18n/da-DK/check.ts +25 -25
- package/src/i18n/da-DK/colors.ts +64 -64
- package/src/i18n/da-DK/common.ts +118 -118
- package/src/i18n/da-DK/company.ts +24 -24
- package/src/i18n/da-DK/consents.ts +23 -23
- package/src/i18n/da-DK/forms.ts +116 -116
- package/src/i18n/da-DK/history.ts +35 -35
- package/src/i18n/da-DK/index.ts +49 -49
- package/src/i18n/da-DK/keywords.ts +19 -19
- package/src/i18n/da-DK/library.ts +135 -135
- package/src/i18n/da-DK/licenses.ts +25 -25
- package/src/i18n/da-DK/media.ts +79 -79
- package/src/i18n/da-DK/parts.ts +696 -696
- package/src/i18n/da-DK/preview.ts +13 -13
- package/src/i18n/da-DK/redirects.ts +51 -51
- package/src/i18n/da-DK/seo.ts +20 -20
- package/src/i18n/da-DK/text.ts +35 -35
- package/src/i18n/da-DK/theme.ts +41 -41
- package/src/i18n/en-US/advanced.ts +32 -32
- package/src/i18n/en-US/app.ts +84 -84
- package/src/i18n/en-US/apps.ts +134 -134
- package/src/i18n/en-US/blockSettings.ts +48 -48
- package/src/i18n/en-US/blocks.ts +441 -441
- package/src/i18n/en-US/check.ts +31 -31
- package/src/i18n/en-US/colors.ts +82 -82
- package/src/i18n/en-US/common.ts +144 -144
- package/src/i18n/en-US/company.ts +25 -25
- package/src/i18n/en-US/consents.ts +25 -25
- package/src/i18n/en-US/forms.ts +145 -145
- package/src/i18n/en-US/history.ts +43 -43
- package/src/i18n/en-US/index.ts +51 -51
- package/src/i18n/en-US/keywords.ts +24 -24
- package/src/i18n/en-US/library.ts +176 -176
- package/src/i18n/en-US/licenses.ts +36 -36
- package/src/i18n/en-US/media.ts +80 -80
- package/src/i18n/en-US/parts.ts +718 -718
- package/src/i18n/en-US/preview.ts +15 -15
- package/src/i18n/en-US/redirects.ts +66 -66
- package/src/i18n/en-US/seo.ts +26 -26
- package/src/i18n/en-US/text.ts +41 -41
- package/src/i18n/en-US/theme.ts +41 -41
- package/src/i18n/index.ts +124 -124
- package/src/icon.tsx +160 -160
- package/src/iconPacks.ts +89 -89
- package/src/images.ts +163 -163
- package/src/{licenses.ts → licenseData.ts} +79 -79
- package/src/markdown.mjs +204 -204
- package/src/nav.ts +68 -68
- package/src/notFound.ts +28 -28
- package/src/{notifications.ts → notificationData.ts} +223 -223
- package/src/pagePreview.tsx +204 -204
- package/src/r2Caching.ts +55 -55
- package/src/{redirects.ts → redirectData.ts} +149 -149
- package/src/registry.tsx +188 -188
- package/src/schema.ts +417 -417
- package/src/sections.mjs +303 -303
- package/src/seo.ts +333 -333
- package/src/shared.ts +44 -44
- package/src/sidebar.ts +31 -31
- package/src/site.ts +317 -317
- package/src/standard/Block.astro +19 -19
- package/src/standard/BlockSite.astro +18 -18
- package/src/standard/accordion/index.tsx +47 -47
- package/src/standard/accordion/load.ts +23 -23
- package/src/standard/accordion/shared.ts +15 -15
- package/src/standard/accordion/view.ts +32 -32
- package/src/standard/buttons/fields.ts +98 -98
- package/src/standard/buttons/index.tsx +23 -23
- package/src/standard/buttons/load.ts +34 -34
- package/src/standard/buttons/shared.ts +12 -12
- package/src/standard/buttons/view.ts +30 -30
- package/src/standard/cards/index.tsx +71 -71
- package/src/standard/cards/load.ts +17 -17
- package/src/standard/cards/shared.ts +27 -27
- package/src/standard/cards/view.ts +29 -29
- package/src/standard/checklist/index.tsx +27 -27
- package/src/standard/checklist/load.ts +5 -5
- package/src/standard/checklist/view.ts +13 -13
- package/src/standard/cookies/index.tsx +17 -17
- package/src/standard/cookies/list.ts +56 -56
- package/src/standard/cookies/load.ts +11 -11
- package/src/standard/cookies/shared.ts +20 -20
- package/src/standard/cookies/view.ts +28 -28
- package/src/standard/faq/index.tsx +29 -29
- package/src/standard/faq/load.ts +14 -14
- package/src/standard/faq/view.ts +21 -21
- package/src/standard/head.ts +23 -23
- package/src/standard/hero/fields.ts +48 -48
- package/src/standard/hero/index.tsx +57 -57
- package/src/standard/hero/load.ts +23 -23
- package/src/standard/hero/view.ts +38 -38
- package/src/standard/links/index.tsx +41 -41
- package/src/standard/links/load.ts +17 -17
- package/src/standard/links/view.ts +25 -25
- package/src/standard/list/index.tsx +50 -50
- package/src/standard/list/load.ts +5 -5
- package/src/standard/list/view.ts +18 -18
- package/src/standard/load.ts +7 -7
- package/src/standard/notice/index.tsx +30 -30
- package/src/standard/notice/load.ts +16 -16
- package/src/standard/notice/view.ts +10 -10
- package/src/standard/points/index.tsx +42 -42
- package/src/standard/points/load.ts +5 -5
- package/src/standard/points/view.ts +12 -12
- package/src/standard/posts/index.tsx +132 -132
- package/src/standard/posts/load.ts +36 -36
- package/src/standard/posts/shared.ts +21 -21
- package/src/standard/posts/view.ts +63 -63
- package/src/standard/pricecards/index.tsx +57 -57
- package/src/standard/pricecards/load.ts +11 -11
- package/src/standard/pricecards/view.ts +50 -50
- package/src/standard/sharedTexts.ts +6 -6
- package/src/standard/site.ts +124 -124
- package/src/standard/siteLooks.ts +19 -19
- package/src/standard/sites.ts +13 -13
- package/src/standard/steps/index.tsx +28 -28
- package/src/standard/steps/load.ts +5 -5
- package/src/standard/steps/view.ts +11 -11
- package/src/standard/testimonials/index.tsx +87 -87
- package/src/standard/testimonials/list.ts +43 -43
- package/src/standard/testimonials/load.ts +58 -58
- package/src/standard/testimonials/shared.ts +13 -13
- package/src/standard/testimonials/view.ts +76 -76
- package/src/standard/themeBlocks.ts +13 -13
- package/src/standard/video/index.tsx +23 -23
- package/src/standard/video/load.ts +10 -10
- package/src/standard/video/view.ts +42 -42
- package/src/standard/view.tsx +105 -105
- package/src/standard/views.ts +37 -37
- package/src/store.ts +479 -499
- package/src/theme.ts +90 -90
- package/src/themeUi.ts +97 -97
- package/src/themes.ts +91 -91
- package/src/ui.tsx +3402 -3402
- package/src/virtual.d.ts +5 -5
- package/src/when.ts +22 -22
- package/starter/.githooks/pre-push +4 -4
- package/starter/.nvmrc +1 -1
- package/starter/.prettierignore +11 -11
- package/starter/.prettierrc.json +7 -7
- package/starter/README.md +27 -26
- package/starter/astro.config.mjs +5 -5
- package/starter/package.json +67 -67
- package/starter/public/_redirects +1 -1
- package/starter/public/favicon.svg +1 -1
- package/starter/public/logo.svg +1 -1
- package/starter/src/content/pages/blog.md +8 -8
- package/starter/src/content/pages/forside.md +9 -9
- package/starter/src/content/pages/kontakt.md +7 -7
- package/starter/src/content/pages/privatlivspolitik.md +9 -9
- package/starter/src/content/pages/siden-findes-ikke.md +7 -7
- package/starter/src/content.config.ts +2 -2
- package/starter/src/data/apps.json +1 -1
- package/starter/src/data/block-settings.json +3 -3
- package/starter/src/data/blocks.json +1 -1
- package/starter/src/data/booking.json +6 -6
- package/starter/src/data/colors.json +70 -70
- package/starter/src/data/contact.json +8 -8
- package/starter/src/data/cookies.json +21 -21
- package/starter/src/data/csp.json +1 -1
- package/starter/src/data/footer.json +15 -15
- package/starter/src/data/internal-links.json +4 -4
- package/starter/src/data/menu.json +4 -4
- package/starter/src/data/mobile-menu.json +4 -4
- package/starter/src/data/old-addresses.json +1 -1
- package/starter/src/data/redirects.json +1 -1
- package/starter/src/data/standard-pages.json +8 -8
- package/starter/src/data/theme.json +1 -1
- package/starter/src/env.d.ts +2 -2
- package/starter/src/site/config.ts +13 -13
- package/starter/src/site/worker.js +14 -14
- package/starter/tsconfig.json +17 -17
- package/starter/worker/apps.js +6 -6
- package/starter/wrangler.jsonc +39 -39
- package/theme/LICENSE +21 -21
- package/theme/blocks/ArrowLink.tsx +14 -14
- package/theme/blocks/BlockHead.tsx +26 -26
- package/theme/blocks/Panel.tsx +32 -32
- package/theme/blocks/Person.tsx +26 -26
- package/theme/blocks/accordion/PageRow.tsx +25 -25
- package/theme/blocks/accordion/View.tsx +17 -17
- package/theme/blocks/buttons/Buttons.tsx +28 -28
- package/theme/blocks/buttons/View.tsx +12 -12
- package/theme/blocks/cards/LinkCards.tsx +72 -72
- package/theme/blocks/cards/View.tsx +20 -20
- package/theme/blocks/checklist/Checks.tsx +15 -15
- package/theme/blocks/checklist/View.tsx +14 -14
- package/theme/blocks/cookies/View.tsx +36 -36
- package/theme/blocks/faq/Accordion.tsx +34 -34
- package/theme/blocks/faq/View.tsx +16 -16
- package/theme/blocks/faq/script.ts +56 -56
- package/theme/blocks/hero/View.tsx +44 -44
- package/theme/blocks/links/LinkGroups.tsx +24 -24
- package/theme/blocks/links/View.tsx +17 -17
- package/theme/blocks/list/Rows.tsx +24 -24
- package/theme/blocks/list/View.tsx +14 -14
- package/theme/blocks/notice/View.tsx +13 -13
- package/theme/blocks/points/PointList.tsx +34 -34
- package/theme/blocks/points/View.tsx +14 -14
- package/theme/blocks/posts/View.tsx +26 -26
- package/theme/blocks/pricecards/View.tsx +40 -40
- package/theme/blocks/steps/StepList.tsx +23 -23
- package/theme/blocks/steps/View.tsx +14 -14
- package/theme/blocks/testimonials/List.tsx +46 -46
- package/theme/blocks/testimonials/Slider.tsx +44 -44
- package/theme/blocks/testimonials/Testimonial.tsx +124 -124
- package/theme/blocks/testimonials/View.tsx +21 -21
- package/theme/blocks/testimonials/script.ts +52 -52
- package/theme/blocks/video/View.tsx +41 -41
- package/theme/components/ActionBar.astro +63 -63
- package/theme/components/AppSlot.astro +21 -21
- package/theme/components/ArrowLink.tsx +21 -21
- package/theme/components/BlogIndex.astro +48 -48
- package/theme/components/BlogPosts.astro +18 -18
- package/theme/components/BlogPosts.tsx +45 -45
- package/theme/components/BookButton.tsx +22 -22
- package/theme/components/Container.astro +11 -11
- package/theme/components/CookieConsent.astro +121 -121
- package/theme/components/EndBlock.astro +21 -21
- package/theme/components/FontPreload.astro +6 -6
- package/theme/components/Footer.astro +85 -85
- package/theme/components/Header.astro +186 -186
- package/theme/components/Icon.astro +16 -16
- package/theme/components/Img.astro +29 -29
- package/theme/components/Img.tsx +33 -33
- package/theme/components/Inline.astro +11 -11
- package/theme/components/Logo.astro +23 -23
- package/theme/components/LogoMark.astro +10 -10
- package/theme/components/Markdown.astro +17 -17
- package/theme/components/MobileMenu.tsx +224 -224
- package/theme/components/MobileNav.astro +33 -33
- package/theme/components/PageHeader.astro +22 -22
- package/theme/components/PageSection.astro +24 -24
- package/theme/components/PhoneButton.tsx +11 -11
- package/theme/components/Popup.astro +145 -145
- package/theme/components/PopupButton.tsx +24 -24
- package/theme/components/PopupView.tsx +48 -48
- package/theme/components/PostList.tsx +58 -58
- package/theme/components/PostMeta.tsx +17 -17
- package/theme/components/RichText.astro +28 -28
- package/theme/components/Section.astro +29 -29
- package/theme/components/SectionHeading.tsx +8 -8
- package/theme/components/TextSection.astro +16 -16
- package/theme/components/home/PageBlock.astro +19 -19
- package/theme/components/home/Text.astro +13 -13
- package/theme/components/loadPopup.ts +22 -22
- package/theme/components/loadPosts.ts +16 -16
- package/theme/components/posts.ts +15 -15
- package/theme/editor/looks.mjs +7 -7
- package/theme/editor/previews.tsx +56 -56
- package/theme/layouts/Base.astro +273 -273
- package/theme/layouts/PageLayout.astro +126 -126
- package/theme/layouts/PostLayout.astro +137 -137
- package/theme/scripts/motion.ts +29 -29
- package/theme/styles/base.css +320 -320
- package/theme/styles/blocks.css +1808 -1808
- package/theme/styles/components.css +206 -206
- package/theme/styles/global.css +1302 -1302
- package/theme/styles/ui.css +6544 -6544
- package/theme/templates/Blog.astro +38 -38
- package/theme/templates/Category.astro +19 -19
- package/theme/templates/Home.astro +36 -36
- package/theme/templates/New.astro +68 -68
- package/theme/templates/NotFound.astro +117 -117
- package/theme/theme.json +28 -28
- package/theme/ui/Badge.tsx +45 -45
- package/theme/ui/BottomSheet.tsx +148 -148
- package/theme/ui/Button.tsx +79 -79
- package/theme/ui/ButtonGroup.tsx +31 -31
- package/theme/ui/Card.tsx +45 -45
- package/theme/ui/Carousel.tsx +124 -124
- package/theme/ui/Checkbox.tsx +59 -59
- package/theme/ui/Chip.tsx +101 -101
- package/theme/ui/ChipSet.tsx +27 -27
- package/theme/ui/DatePicker.tsx +149 -149
- package/theme/ui/DatePickerContainer.tsx +316 -316
- package/theme/ui/Dialog.tsx +100 -100
- package/theme/ui/Divider.tsx +27 -27
- package/theme/ui/ExposedDropdownMenu.tsx +77 -77
- package/theme/ui/Fab.tsx +88 -88
- package/theme/ui/FabMenu.tsx +67 -67
- package/theme/ui/IconButton.tsx +78 -78
- package/theme/ui/List.tsx +287 -287
- package/theme/ui/LoadingIndicator.tsx +29 -29
- package/theme/ui/Menu.tsx +278 -278
- package/theme/ui/NavigationBar.tsx +62 -62
- package/theme/ui/NavigationDrawer.tsx +80 -80
- package/theme/ui/NavigationRail.tsx +154 -154
- package/theme/ui/ProgressIndicator.tsx +162 -162
- package/theme/ui/RadioButton.tsx +50 -50
- package/theme/ui/Search.tsx +129 -129
- package/theme/ui/SegmentedButton.tsx +49 -49
- package/theme/ui/SideSheet.tsx +54 -54
- package/theme/ui/Slider.tsx +155 -155
- package/theme/ui/Snackbar.tsx +67 -67
- package/theme/ui/SplitButton.tsx +67 -67
- package/theme/ui/Switch.tsx +60 -60
- package/theme/ui/Tabs.tsx +114 -114
- package/theme/ui/TextField.tsx +278 -278
- package/theme/ui/TimePicker.tsx +128 -128
- package/theme/ui/TimePickerContainer.tsx +234 -234
- package/theme/ui/Toolbar.tsx +67 -67
- package/theme/ui/Tooltip.tsx +58 -58
- package/theme/ui/TopAppBar.tsx +77 -77
- package/theme/ui/bottomSheet.script.ts +8 -8
- package/theme/ui/{bottomSheet.ts → bottomSheetControl.ts} +211 -211
- package/theme/ui/carousel.script.ts +28 -28
- package/theme/ui/carouselLayout.ts +229 -229
- package/theme/ui/checkbox.script.ts +8 -8
- package/theme/ui/datePicker.script.ts +302 -302
- package/theme/ui/dates.ts +185 -185
- package/theme/ui/{dialog.ts → dialogControl.ts} +48 -48
- package/theme/ui/dropdownMenu.script.ts +166 -166
- package/theme/ui/fabMenu.script.ts +57 -57
- package/theme/ui/navigationRail.script.ts +47 -47
- package/theme/ui/ripple.script.ts +159 -159
- package/theme/ui/search.script.ts +92 -92
- package/theme/ui/{sideSheet.ts → sideSheetControl.ts} +48 -48
- package/theme/ui/slider.script.ts +12 -12
- package/theme/ui/sliderUpdate.ts +52 -52
- package/theme/ui/snackbar.script.ts +16 -16
- package/theme/ui/splitButton.script.ts +63 -63
- package/theme/ui/tabs.script.ts +48 -48
- package/theme/ui/textField.script.ts +17 -17
- package/theme/ui/textFieldUpdate.ts +44 -44
- package/theme/ui/timePicker.script.ts +248 -248
- package/theme/ui/toolbar.script.ts +43 -43
- package/theme/ui/tooltip.script.ts +68 -68
- package/worker/consent.js +141 -141
- package/worker/editor-github.js +167 -167
- package/worker/editor-host.js +74 -74
- package/worker/files.js +401 -401
- package/worker/github.js +36 -36
- package/worker/index.js +188 -184
- package/worker/not-found.js +97 -97
- package/worker/oauth.js +95 -95
- package/worker/publish.js +52 -52
- package/worker/push.js +270 -270
- package/worker/r2-status.js +50 -50
- package/worker/session.js +58 -58
- package/worker/store.js +46 -0
|
@@ -1,79 +1,79 @@
|
|
|
1
|
-
// The licences of the third-party work the site and the editor are made with ("Licenser" under "Indstillinger",
|
|
2
|
-
// Licenses.tsx), as the build finds them (/editor/licenses.json, licensesIntegration in packages/editor/lib/licenses.mjs),
|
|
3
|
-
// what an app (defineApp) and a theme (theme.json) declare (their own licence and the third-party work they bring), and
|
|
4
|
-
// what the store's catalog has of them (scripts/store-release.mjs, storeLicenses).
|
|
5
|
-
|
|
6
|
-
/** What a third-party work is to the site: a font, icons, code (a library, also styles) or pictures. */
|
|
7
|
-
export type LicenseKind = 'font' | 'icons' | 'library' | 'image';
|
|
8
|
-
|
|
9
|
-
/** A third-party work an app or a theme brings, as it declares it (`thirdParty`): an npm package it imports (its
|
|
10
|
-
* version, who made it, its licence and its text are its folder's; `author`, and `file`, a file in the app's or the
|
|
11
|
-
* theme's folder with the licence's text, for a package that has neither); or another work (a font or pictures in its
|
|
12
|
-
* folder), with its name, who made it, its licence's name and the file in its folder with its text. A theme's icon
|
|
13
|
-
* packs (icon-packs/) are not declared here: each pack's manifest says its licence. */
|
|
14
|
-
export type ThirdParty =
|
|
15
|
-
| { package: string; kind: LicenseKind; author?: string; file?: string }
|
|
16
|
-
| { name: string; version?: string; author: string; license: string; file: string; kind: LicenseKind };
|
|
17
|
-
|
|
18
|
-
/** The licence of one's own work that grants nothing ("all rights reserved"), as npm writes it. */
|
|
19
|
-
export const UNLICENSED = 'UNLICENSED';
|
|
20
|
-
|
|
21
|
-
/** Who brings a work: the editor, the site's own code, or an app or a theme (`app/<id>`, `tema/<id>`, LicenseOwner.id). */
|
|
22
|
-
export type LicenseWhere = 'editor' | 'site' | `app/${string}` | `tema/${string}`;
|
|
23
|
-
|
|
24
|
-
/** A third-party work as the build found it: its id (a package's name; `ikoner/<id>` for an icon set; `<owner>/<name>`
|
|
25
|
-
* for another work an app or a theme declares), its name, version, who made it, its licence's name and text (`standard`:
|
|
26
|
-
* the licence's standard text, as the package has none of its own), what it is, who brings it (`where`, none for an
|
|
27
|
-
* icon set or a work only an app or a theme not in use brings) and through which packages (`via`, when the site does not
|
|
28
|
-
* import it itself). `shipped: false`: brought by an app or a theme the site is built with, but not in what is downloaded (the Worker's, the
|
|
29
|
-
* build's). */
|
|
30
|
-
export type LicensedWork = {
|
|
31
|
-
id: string;
|
|
32
|
-
name: string;
|
|
33
|
-
version: string | null;
|
|
34
|
-
author: string;
|
|
35
|
-
license: string;
|
|
36
|
-
text: string;
|
|
37
|
-
standard?: boolean;
|
|
38
|
-
kind: LicenseKind;
|
|
39
|
-
where: LicenseWhere[];
|
|
40
|
-
via?: string[];
|
|
41
|
-
shipped?: false;
|
|
42
|
-
};
|
|
43
|
-
|
|
44
|
-
/** An app or a theme with its own licence (`text`: LICENSE in its folder, none when it is UNLICENSED) and the works it
|
|
45
|
-
* brings (their ids: those it declares, and those shipped through them alone), and whether the site is built with it. */
|
|
46
|
-
export type LicenseOwner = {
|
|
47
|
-
id: `app/${string}` | `tema/${string}`;
|
|
48
|
-
kind: 'app' | 'theme';
|
|
49
|
-
/** Its folder's name in src/apps/ or src/themes/. */
|
|
50
|
-
key: string;
|
|
51
|
-
name: string;
|
|
52
|
-
version: string | null;
|
|
53
|
-
author: string;
|
|
54
|
-
license: string;
|
|
55
|
-
text: string | null;
|
|
56
|
-
works: string[];
|
|
57
|
-
inUse: boolean;
|
|
58
|
-
};
|
|
59
|
-
|
|
60
|
-
/** What the build wrote (/editor/licenses.json). */
|
|
61
|
-
export type LicensesFile = { works: LicensedWork[]; owners: LicenseOwner[] };
|
|
62
|
-
|
|
63
|
-
/** A work an app or a theme declares, as the store's catalog has it: without its text. */
|
|
64
|
-
export type StoreLicense = Pick<LicensedWork, 'name' | 'version' | 'author' | 'license' | 'kind'>;
|
|
65
|
-
|
|
66
|
-
/** An app's or a theme's licences as the store's catalog has them: its own licence's name and what it brings. */
|
|
67
|
-
export type StoreLicenses = { license: string; works: StoreLicense[] };
|
|
68
|
-
|
|
69
|
-
// The file, fetched once each time the editor opens: undefined while it loads, null when there is none (the site is not
|
|
70
|
-
// built since it came, or the editor is offline).
|
|
71
|
-
let loaded: Promise<LicensesFile | null> | undefined;
|
|
72
|
-
|
|
73
|
-
/** The licences as the site was last built (/editor/licenses.json). */
|
|
74
|
-
export function loadLicenses(): Promise<LicensesFile | null> {
|
|
75
|
-
loaded ??= fetch('/editor/licenses.json', { cache: 'no-store' })
|
|
76
|
-
.then((res) => (res.ok ? (res.json() as Promise<LicensesFile>) : null))
|
|
77
|
-
.catch(() => null);
|
|
78
|
-
return loaded;
|
|
79
|
-
}
|
|
1
|
+
// The licences of the third-party work the site and the editor are made with ("Licenser" under "Indstillinger",
|
|
2
|
+
// Licenses.tsx), as the build finds them (/editor/licenses.json, licensesIntegration in packages/editor/lib/licenses.mjs),
|
|
3
|
+
// what an app (defineApp) and a theme (theme.json) declare (their own licence and the third-party work they bring), and
|
|
4
|
+
// what the store's catalog has of them (scripts/store-release.mjs, storeLicenses).
|
|
5
|
+
|
|
6
|
+
/** What a third-party work is to the site: a font, icons, code (a library, also styles) or pictures. */
|
|
7
|
+
export type LicenseKind = 'font' | 'icons' | 'library' | 'image';
|
|
8
|
+
|
|
9
|
+
/** A third-party work an app or a theme brings, as it declares it (`thirdParty`): an npm package it imports (its
|
|
10
|
+
* version, who made it, its licence and its text are its folder's; `author`, and `file`, a file in the app's or the
|
|
11
|
+
* theme's folder with the licence's text, for a package that has neither); or another work (a font or pictures in its
|
|
12
|
+
* folder), with its name, who made it, its licence's name and the file in its folder with its text. A theme's icon
|
|
13
|
+
* packs (icon-packs/) are not declared here: each pack's manifest says its licence. */
|
|
14
|
+
export type ThirdParty =
|
|
15
|
+
| { package: string; kind: LicenseKind; author?: string; file?: string }
|
|
16
|
+
| { name: string; version?: string; author: string; license: string; file: string; kind: LicenseKind };
|
|
17
|
+
|
|
18
|
+
/** The licence of one's own work that grants nothing ("all rights reserved"), as npm writes it. */
|
|
19
|
+
export const UNLICENSED = 'UNLICENSED';
|
|
20
|
+
|
|
21
|
+
/** Who brings a work: the editor, the site's own code, or an app or a theme (`app/<id>`, `tema/<id>`, LicenseOwner.id). */
|
|
22
|
+
export type LicenseWhere = 'editor' | 'site' | `app/${string}` | `tema/${string}`;
|
|
23
|
+
|
|
24
|
+
/** A third-party work as the build found it: its id (a package's name; `ikoner/<id>` for an icon set; `<owner>/<name>`
|
|
25
|
+
* for another work an app or a theme declares), its name, version, who made it, its licence's name and text (`standard`:
|
|
26
|
+
* the licence's standard text, as the package has none of its own), what it is, who brings it (`where`, none for an
|
|
27
|
+
* icon set or a work only an app or a theme not in use brings) and through which packages (`via`, when the site does not
|
|
28
|
+
* import it itself). `shipped: false`: brought by an app or a theme the site is built with, but not in what is downloaded (the Worker's, the
|
|
29
|
+
* build's). */
|
|
30
|
+
export type LicensedWork = {
|
|
31
|
+
id: string;
|
|
32
|
+
name: string;
|
|
33
|
+
version: string | null;
|
|
34
|
+
author: string;
|
|
35
|
+
license: string;
|
|
36
|
+
text: string;
|
|
37
|
+
standard?: boolean;
|
|
38
|
+
kind: LicenseKind;
|
|
39
|
+
where: LicenseWhere[];
|
|
40
|
+
via?: string[];
|
|
41
|
+
shipped?: false;
|
|
42
|
+
};
|
|
43
|
+
|
|
44
|
+
/** An app or a theme with its own licence (`text`: LICENSE in its folder, none when it is UNLICENSED) and the works it
|
|
45
|
+
* brings (their ids: those it declares, and those shipped through them alone), and whether the site is built with it. */
|
|
46
|
+
export type LicenseOwner = {
|
|
47
|
+
id: `app/${string}` | `tema/${string}`;
|
|
48
|
+
kind: 'app' | 'theme';
|
|
49
|
+
/** Its folder's name in src/apps/ or src/themes/. */
|
|
50
|
+
key: string;
|
|
51
|
+
name: string;
|
|
52
|
+
version: string | null;
|
|
53
|
+
author: string;
|
|
54
|
+
license: string;
|
|
55
|
+
text: string | null;
|
|
56
|
+
works: string[];
|
|
57
|
+
inUse: boolean;
|
|
58
|
+
};
|
|
59
|
+
|
|
60
|
+
/** What the build wrote (/editor/licenses.json). */
|
|
61
|
+
export type LicensesFile = { works: LicensedWork[]; owners: LicenseOwner[] };
|
|
62
|
+
|
|
63
|
+
/** A work an app or a theme declares, as the store's catalog has it: without its text. */
|
|
64
|
+
export type StoreLicense = Pick<LicensedWork, 'name' | 'version' | 'author' | 'license' | 'kind'>;
|
|
65
|
+
|
|
66
|
+
/** An app's or a theme's licences as the store's catalog has them: its own licence's name and what it brings. */
|
|
67
|
+
export type StoreLicenses = { license: string; works: StoreLicense[] };
|
|
68
|
+
|
|
69
|
+
// The file, fetched once each time the editor opens: undefined while it loads, null when there is none (the site is not
|
|
70
|
+
// built since it came, or the editor is offline).
|
|
71
|
+
let loaded: Promise<LicensesFile | null> | undefined;
|
|
72
|
+
|
|
73
|
+
/** The licences as the site was last built (/editor/licenses.json). */
|
|
74
|
+
export function loadLicenses(): Promise<LicensesFile | null> {
|
|
75
|
+
loaded ??= fetch('/editor/licenses.json', { cache: 'no-store' })
|
|
76
|
+
.then((res) => (res.ok ? (res.json() as Promise<LicensesFile>) : null))
|
|
77
|
+
.catch(() => null);
|
|
78
|
+
return loaded;
|
|
79
|
+
}
|
package/src/markdown.mjs
CHANGED
|
@@ -1,204 +1,204 @@
|
|
|
1
|
-
// The Milkdown setup shared by the editor (/editor/) and packages/editor/scripts/editor-roundtrip.mjs, so the check
|
|
2
|
-
// runs the same Markdown parser and writer as the browser.
|
|
3
|
-
import { Editor, editorViewCtx, rootCtx, defaultValueCtx, remarkStringifyOptionsCtx, serializerCtx } from '@milkdown/kit/core';
|
|
4
|
-
import { commonmark } from '@milkdown/kit/preset/commonmark';
|
|
5
|
-
import { gfm } from '@milkdown/kit/preset/gfm';
|
|
6
|
-
import { $markSchema, $nodeSchema, $prose, $remark } from '@milkdown/kit/utils';
|
|
7
|
-
import { Plugin } from '@milkdown/kit/prose/state';
|
|
8
|
-
import { blockHtml, parseBlock } from '../lib/blocks.mjs';
|
|
9
|
-
import { COLOR_CLOSE, TEXT_COLORS, colorClass, colorOpen, colorOpened } from '../lib/text-colors.mjs';
|
|
10
|
-
|
|
11
|
-
// Write Markdown the way imported files are written: "- " bullets and
|
|
12
|
-
// "* * *" rules, so a save changes as few lines as possible.
|
|
13
|
-
const stringify = { bullet: '-', listItemIndent: 'tab', rule: '*', ruleSpaces: true };
|
|
14
|
-
|
|
15
|
-
// The site's blocks in the text (packages/editor/lib/blocks.mjs), read from and written back as their line of HTML.
|
|
16
|
-
// Milkdown puts HTML at the top of the text in a paragraph; a paragraph that is only a block becomes
|
|
17
|
-
// a siteBlock node (with its type and props) before the text is read. Any type is read: the sections
|
|
18
|
-
// of the fixed pages are blocks too (sections.mjs); the site shows only its own (RichText.astro).
|
|
19
|
-
// Other HTML on a line of its own (YouTube, Vimeo, Calendly, an imported table) is a block too, of the
|
|
20
|
-
// type HTML, with the HTML as it is as its `code`, and written back as it was.
|
|
21
|
-
export const HTML = 'html';
|
|
22
|
-
const remarkSiteBlocks = $remark('remarkSiteBlocks', () => () => (tree) => {
|
|
23
|
-
tree.children = tree.children.map((child) => {
|
|
24
|
-
const only = child.type === 'paragraph' && child.children?.length === 1 ? child.children[0] : child;
|
|
25
|
-
if (only.type !== 'html') return child;
|
|
26
|
-
const block = parseBlock(String(only.value), null);
|
|
27
|
-
return block
|
|
28
|
-
? { type: 'siteBlock', blockType: block.type, props: block.props }
|
|
29
|
-
: { type: 'siteBlock', blockType: HTML, props: { code: String(only.value) } };
|
|
30
|
-
});
|
|
31
|
-
});
|
|
32
|
-
|
|
33
|
-
// One node per block, with its type and its props. How it looks in the editor: MarkdownEditor.tsx.
|
|
34
|
-
/** @type {import('@milkdown/kit/utils').$NodeSchema<'siteBlock'>} */
|
|
35
|
-
export const siteBlockSchema = $nodeSchema('siteBlock', () => ({
|
|
36
|
-
group: 'block',
|
|
37
|
-
atom: true,
|
|
38
|
-
selectable: true,
|
|
39
|
-
attrs: { type: { default: '' }, props: { default: {} } },
|
|
40
|
-
parseDOM: [{ tag: 'div[data-site-block]', getAttrs: (dom) => parseBlock(dom.dataset.siteBlock ?? '', null) ?? false }],
|
|
41
|
-
toDOM: (node) => ['div', { 'data-site-block': blockHtml(node.attrs.type, node.attrs.props) }],
|
|
42
|
-
parseMarkdown: {
|
|
43
|
-
match: (node) => node.type === 'siteBlock',
|
|
44
|
-
runner: (state, node, type) => {
|
|
45
|
-
state.addNode(type, { type: node.blockType, props: node.props });
|
|
46
|
-
},
|
|
47
|
-
},
|
|
48
|
-
toMarkdown: {
|
|
49
|
-
match: (node) => node.type.name === 'siteBlock',
|
|
50
|
-
runner: (state, node) => {
|
|
51
|
-
const { type, props } = node.attrs;
|
|
52
|
-
state.addNode('html', undefined, type === HTML ? String(props.code ?? '') : blockHtml(type, props));
|
|
53
|
-
},
|
|
54
|
-
},
|
|
55
|
-
}));
|
|
56
|
-
|
|
57
|
-
// A word or more in one of the site's colours (packages/editor/lib/text-colors.mjs): in the Markdown the HTML around
|
|
58
|
-
// it, <span class="color-accent">…</span>, which Milkdown would read as two pieces of HTML with the text between them;
|
|
59
|
-
// read as the text with the colour (a mark), and written back as the same HTML. A piece of HTML without its end, or
|
|
60
|
-
// another span, stays HTML.
|
|
61
|
-
function colorRuns(children) {
|
|
62
|
-
const out = [];
|
|
63
|
-
for (let i = 0; i < children.length; i++) {
|
|
64
|
-
const color = children[i].type === 'html' ? colorOpened(children[i].value) : null;
|
|
65
|
-
let end = -1;
|
|
66
|
-
for (let j = i + 1, depth = 0; color && j < children.length && end < 0; j++) {
|
|
67
|
-
const node = children[j];
|
|
68
|
-
if (node.type !== 'html') continue;
|
|
69
|
-
if (/^<span\b/.test(node.value)) depth++;
|
|
70
|
-
else if (node.value === COLOR_CLOSE && depth-- === 0) end = j;
|
|
71
|
-
}
|
|
72
|
-
if (end < 0) out.push(children[i]);
|
|
73
|
-
else {
|
|
74
|
-
out.push({ type: 'textColor', color, children: children.slice(i + 1, end) });
|
|
75
|
-
i = end;
|
|
76
|
-
}
|
|
77
|
-
}
|
|
78
|
-
return out;
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
function textColorMarkdown(node, _, state, info) {
|
|
82
|
-
const tracker = state.createTracker(info);
|
|
83
|
-
let value = tracker.move(colorOpen(node.color));
|
|
84
|
-
value += tracker.move(state.containerPhrasing(node, { ...tracker.current(), before: '>', after: '<' }));
|
|
85
|
-
return value + tracker.move(COLOR_CLOSE);
|
|
86
|
-
}
|
|
87
|
-
textColorMarkdown.peek = () => '<';
|
|
88
|
-
|
|
89
|
-
const remarkTextColors = $remark(
|
|
90
|
-
'remarkTextColors',
|
|
91
|
-
() =>
|
|
92
|
-
function () {
|
|
93
|
-
const data = this.data();
|
|
94
|
-
(data.toMarkdownExtensions ??= []).push({ handlers: { textColor: textColorMarkdown } });
|
|
95
|
-
const walk = (node) => {
|
|
96
|
-
if (!node.children) return;
|
|
97
|
-
node.children = colorRuns(node.children);
|
|
98
|
-
node.children.forEach(walk);
|
|
99
|
-
};
|
|
100
|
-
return walk;
|
|
101
|
-
},
|
|
102
|
-
);
|
|
103
|
-
|
|
104
|
-
/** @type {import('@milkdown/kit/utils').$MarkSchema<'textColor'>} */
|
|
105
|
-
export const textColorSchema = $markSchema('textColor', () => ({
|
|
106
|
-
attrs: { color: { default: TEXT_COLORS[0] } },
|
|
107
|
-
parseDOM: TEXT_COLORS.map((color) => ({ tag: `span.${colorClass(color)}`, attrs: { color } })),
|
|
108
|
-
toDOM: (mark) => ['span', { class: colorClass(mark.attrs.color) }],
|
|
109
|
-
parseMarkdown: {
|
|
110
|
-
match: (node) => node.type === 'textColor',
|
|
111
|
-
runner: (state, node, markType) => {
|
|
112
|
-
state.openMark(markType, { color: node.color });
|
|
113
|
-
state.next(node.children);
|
|
114
|
-
state.closeMark(markType);
|
|
115
|
-
},
|
|
116
|
-
},
|
|
117
|
-
toMarkdown: {
|
|
118
|
-
match: (mark) => mark.type.name === 'textColor',
|
|
119
|
-
runner: (state, mark) => {
|
|
120
|
-
state.withMark(mark, 'textColor', undefined, { color: mark.attrs.color });
|
|
121
|
-
},
|
|
122
|
-
},
|
|
123
|
-
}));
|
|
124
|
-
|
|
125
|
-
/** A Milkdown editor of the text, in root (not created yet). @param {HTMLElement | null} root @param {string} markdown
|
|
126
|
-
* @returns {import('@milkdown/kit/core').Editor} */
|
|
127
|
-
export function makeEditor(root, markdown) {
|
|
128
|
-
return Editor.make()
|
|
129
|
-
.config((ctx) => {
|
|
130
|
-
ctx.set(rootCtx, root);
|
|
131
|
-
ctx.set(defaultValueCtx, markdown);
|
|
132
|
-
ctx.update(remarkStringifyOptionsCtx, (options) => ({ ...options, ...stringify }));
|
|
133
|
-
})
|
|
134
|
-
.use(commonmark)
|
|
135
|
-
.use(gfm)
|
|
136
|
-
.use(remarkSiteBlocks)
|
|
137
|
-
.use(siteBlockSchema)
|
|
138
|
-
.use(remarkTextColors)
|
|
139
|
-
.use(textColorSchema);
|
|
140
|
-
}
|
|
141
|
-
|
|
142
|
-
// The text in parts, for a fixed page's sections (sections.mjs): each block, each heading at the top
|
|
143
|
-
// level ("Overskrift", H2), and the Markdown of the text between them. Empty paragraphs (the lines
|
|
144
|
-
// kept free between two blocks to write in), empty headings (left when one is deleted) and the page's H1
|
|
145
|
-
// (no section's) are left out.
|
|
146
|
-
export function partsOf(ctx) {
|
|
147
|
-
const doc = ctx.get(editorViewCtx).state.doc;
|
|
148
|
-
const serialize = ctx.get(serializerCtx);
|
|
149
|
-
const parts = [];
|
|
150
|
-
let run = [];
|
|
151
|
-
const flush = () => {
|
|
152
|
-
const markdown = run.length ? serialize(doc.type.create(null, run)).trim() : '';
|
|
153
|
-
if (markdown) parts.push({ markdown });
|
|
154
|
-
run = [];
|
|
155
|
-
};
|
|
156
|
-
doc.forEach((node) => {
|
|
157
|
-
// HTML in a section's text stays in its text.
|
|
158
|
-
if (node.type.name === 'siteBlock' && node.attrs.type !== HTML) {
|
|
159
|
-
flush();
|
|
160
|
-
parts.push({ block: { type: node.attrs.type, props: node.attrs.props } });
|
|
161
|
-
} else if (node.type.name === 'heading' && node.attrs.level === 2) {
|
|
162
|
-
flush();
|
|
163
|
-
parts.push({ heading: node.textContent.trim() });
|
|
164
|
-
} else if (node.type.name === 'heading' && node.attrs.level === 1) {
|
|
165
|
-
flush();
|
|
166
|
-
} else if (!((node.type.name === 'paragraph' || node.type.name === 'heading') && !node.textContent.trim() && !node.childCount))
|
|
167
|
-
run.push(node);
|
|
168
|
-
});
|
|
169
|
-
flush();
|
|
170
|
-
return parts;
|
|
171
|
-
}
|
|
172
|
-
|
|
173
|
-
// Keeps a free line (an empty paragraph) between two blocks and before and after them, so there is
|
|
174
|
-
// always a place to write a text between them. Not part of undo. Used by the editor (MarkdownEditor.tsx)
|
|
175
|
-
// and the check, which writes the text back with the free lines in it.
|
|
176
|
-
/** @type {import('@milkdown/kit/utils').$Prose} */
|
|
177
|
-
export const spacing = $prose(
|
|
178
|
-
() =>
|
|
179
|
-
new Plugin({
|
|
180
|
-
appendTransaction: (_, __, state) => {
|
|
181
|
-
const gaps = [];
|
|
182
|
-
let before = null;
|
|
183
|
-
state.doc.forEach((node, at) => {
|
|
184
|
-
if (node.type.name === 'siteBlock' && (!before || before.type.name === 'siteBlock')) gaps.push(at);
|
|
185
|
-
before = node;
|
|
186
|
-
});
|
|
187
|
-
if (state.doc.lastChild?.type.name === 'siteBlock') gaps.push(state.doc.content.size);
|
|
188
|
-
if (!gaps.length) return null;
|
|
189
|
-
const tr = state.tr;
|
|
190
|
-
for (const at of gaps.reverse()) tr.insert(at, state.schema.nodes.paragraph.create());
|
|
191
|
-
return tr.setMeta('addToHistory', false);
|
|
192
|
-
},
|
|
193
|
-
}),
|
|
194
|
-
);
|
|
195
|
-
|
|
196
|
-
// The Markdown of the text, without its empty paragraphs (the free lines between the blocks).
|
|
197
|
-
export function markdownOf(ctx) {
|
|
198
|
-
const doc = ctx.get(editorViewCtx).state.doc;
|
|
199
|
-
const kept = [];
|
|
200
|
-
doc.forEach((node) => {
|
|
201
|
-
if (!(node.type.name === 'paragraph' && node.content.size === 0)) kept.push(node);
|
|
202
|
-
});
|
|
203
|
-
return ctx.get(serializerCtx)(doc.type.create(null, kept));
|
|
204
|
-
}
|
|
1
|
+
// The Milkdown setup shared by the editor (/editor/) and packages/editor/scripts/editor-roundtrip.mjs, so the check
|
|
2
|
+
// runs the same Markdown parser and writer as the browser.
|
|
3
|
+
import { Editor, editorViewCtx, rootCtx, defaultValueCtx, remarkStringifyOptionsCtx, serializerCtx } from '@milkdown/kit/core';
|
|
4
|
+
import { commonmark } from '@milkdown/kit/preset/commonmark';
|
|
5
|
+
import { gfm } from '@milkdown/kit/preset/gfm';
|
|
6
|
+
import { $markSchema, $nodeSchema, $prose, $remark } from '@milkdown/kit/utils';
|
|
7
|
+
import { Plugin } from '@milkdown/kit/prose/state';
|
|
8
|
+
import { blockHtml, parseBlock } from '../lib/blocks.mjs';
|
|
9
|
+
import { COLOR_CLOSE, TEXT_COLORS, colorClass, colorOpen, colorOpened } from '../lib/text-colors.mjs';
|
|
10
|
+
|
|
11
|
+
// Write Markdown the way imported files are written: "- " bullets and
|
|
12
|
+
// "* * *" rules, so a save changes as few lines as possible.
|
|
13
|
+
const stringify = { bullet: '-', listItemIndent: 'tab', rule: '*', ruleSpaces: true };
|
|
14
|
+
|
|
15
|
+
// The site's blocks in the text (packages/editor/lib/blocks.mjs), read from and written back as their line of HTML.
|
|
16
|
+
// Milkdown puts HTML at the top of the text in a paragraph; a paragraph that is only a block becomes
|
|
17
|
+
// a siteBlock node (with its type and props) before the text is read. Any type is read: the sections
|
|
18
|
+
// of the fixed pages are blocks too (sections.mjs); the site shows only its own (RichText.astro).
|
|
19
|
+
// Other HTML on a line of its own (YouTube, Vimeo, Calendly, an imported table) is a block too, of the
|
|
20
|
+
// type HTML, with the HTML as it is as its `code`, and written back as it was.
|
|
21
|
+
export const HTML = 'html';
|
|
22
|
+
const remarkSiteBlocks = $remark('remarkSiteBlocks', () => () => (tree) => {
|
|
23
|
+
tree.children = tree.children.map((child) => {
|
|
24
|
+
const only = child.type === 'paragraph' && child.children?.length === 1 ? child.children[0] : child;
|
|
25
|
+
if (only.type !== 'html') return child;
|
|
26
|
+
const block = parseBlock(String(only.value), null);
|
|
27
|
+
return block
|
|
28
|
+
? { type: 'siteBlock', blockType: block.type, props: block.props }
|
|
29
|
+
: { type: 'siteBlock', blockType: HTML, props: { code: String(only.value) } };
|
|
30
|
+
});
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
// One node per block, with its type and its props. How it looks in the editor: MarkdownEditor.tsx.
|
|
34
|
+
/** @type {import('@milkdown/kit/utils').$NodeSchema<'siteBlock'>} */
|
|
35
|
+
export const siteBlockSchema = $nodeSchema('siteBlock', () => ({
|
|
36
|
+
group: 'block',
|
|
37
|
+
atom: true,
|
|
38
|
+
selectable: true,
|
|
39
|
+
attrs: { type: { default: '' }, props: { default: {} } },
|
|
40
|
+
parseDOM: [{ tag: 'div[data-site-block]', getAttrs: (dom) => parseBlock(dom.dataset.siteBlock ?? '', null) ?? false }],
|
|
41
|
+
toDOM: (node) => ['div', { 'data-site-block': blockHtml(node.attrs.type, node.attrs.props) }],
|
|
42
|
+
parseMarkdown: {
|
|
43
|
+
match: (node) => node.type === 'siteBlock',
|
|
44
|
+
runner: (state, node, type) => {
|
|
45
|
+
state.addNode(type, { type: node.blockType, props: node.props });
|
|
46
|
+
},
|
|
47
|
+
},
|
|
48
|
+
toMarkdown: {
|
|
49
|
+
match: (node) => node.type.name === 'siteBlock',
|
|
50
|
+
runner: (state, node) => {
|
|
51
|
+
const { type, props } = node.attrs;
|
|
52
|
+
state.addNode('html', undefined, type === HTML ? String(props.code ?? '') : blockHtml(type, props));
|
|
53
|
+
},
|
|
54
|
+
},
|
|
55
|
+
}));
|
|
56
|
+
|
|
57
|
+
// A word or more in one of the site's colours (packages/editor/lib/text-colors.mjs): in the Markdown the HTML around
|
|
58
|
+
// it, <span class="color-accent">…</span>, which Milkdown would read as two pieces of HTML with the text between them;
|
|
59
|
+
// read as the text with the colour (a mark), and written back as the same HTML. A piece of HTML without its end, or
|
|
60
|
+
// another span, stays HTML.
|
|
61
|
+
function colorRuns(children) {
|
|
62
|
+
const out = [];
|
|
63
|
+
for (let i = 0; i < children.length; i++) {
|
|
64
|
+
const color = children[i].type === 'html' ? colorOpened(children[i].value) : null;
|
|
65
|
+
let end = -1;
|
|
66
|
+
for (let j = i + 1, depth = 0; color && j < children.length && end < 0; j++) {
|
|
67
|
+
const node = children[j];
|
|
68
|
+
if (node.type !== 'html') continue;
|
|
69
|
+
if (/^<span\b/.test(node.value)) depth++;
|
|
70
|
+
else if (node.value === COLOR_CLOSE && depth-- === 0) end = j;
|
|
71
|
+
}
|
|
72
|
+
if (end < 0) out.push(children[i]);
|
|
73
|
+
else {
|
|
74
|
+
out.push({ type: 'textColor', color, children: children.slice(i + 1, end) });
|
|
75
|
+
i = end;
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
return out;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
function textColorMarkdown(node, _, state, info) {
|
|
82
|
+
const tracker = state.createTracker(info);
|
|
83
|
+
let value = tracker.move(colorOpen(node.color));
|
|
84
|
+
value += tracker.move(state.containerPhrasing(node, { ...tracker.current(), before: '>', after: '<' }));
|
|
85
|
+
return value + tracker.move(COLOR_CLOSE);
|
|
86
|
+
}
|
|
87
|
+
textColorMarkdown.peek = () => '<';
|
|
88
|
+
|
|
89
|
+
const remarkTextColors = $remark(
|
|
90
|
+
'remarkTextColors',
|
|
91
|
+
() =>
|
|
92
|
+
function () {
|
|
93
|
+
const data = this.data();
|
|
94
|
+
(data.toMarkdownExtensions ??= []).push({ handlers: { textColor: textColorMarkdown } });
|
|
95
|
+
const walk = (node) => {
|
|
96
|
+
if (!node.children) return;
|
|
97
|
+
node.children = colorRuns(node.children);
|
|
98
|
+
node.children.forEach(walk);
|
|
99
|
+
};
|
|
100
|
+
return walk;
|
|
101
|
+
},
|
|
102
|
+
);
|
|
103
|
+
|
|
104
|
+
/** @type {import('@milkdown/kit/utils').$MarkSchema<'textColor'>} */
|
|
105
|
+
export const textColorSchema = $markSchema('textColor', () => ({
|
|
106
|
+
attrs: { color: { default: TEXT_COLORS[0] } },
|
|
107
|
+
parseDOM: TEXT_COLORS.map((color) => ({ tag: `span.${colorClass(color)}`, attrs: { color } })),
|
|
108
|
+
toDOM: (mark) => ['span', { class: colorClass(mark.attrs.color) }],
|
|
109
|
+
parseMarkdown: {
|
|
110
|
+
match: (node) => node.type === 'textColor',
|
|
111
|
+
runner: (state, node, markType) => {
|
|
112
|
+
state.openMark(markType, { color: node.color });
|
|
113
|
+
state.next(node.children);
|
|
114
|
+
state.closeMark(markType);
|
|
115
|
+
},
|
|
116
|
+
},
|
|
117
|
+
toMarkdown: {
|
|
118
|
+
match: (mark) => mark.type.name === 'textColor',
|
|
119
|
+
runner: (state, mark) => {
|
|
120
|
+
state.withMark(mark, 'textColor', undefined, { color: mark.attrs.color });
|
|
121
|
+
},
|
|
122
|
+
},
|
|
123
|
+
}));
|
|
124
|
+
|
|
125
|
+
/** A Milkdown editor of the text, in root (not created yet). @param {HTMLElement | null} root @param {string} markdown
|
|
126
|
+
* @returns {import('@milkdown/kit/core').Editor} */
|
|
127
|
+
export function makeEditor(root, markdown) {
|
|
128
|
+
return Editor.make()
|
|
129
|
+
.config((ctx) => {
|
|
130
|
+
ctx.set(rootCtx, root);
|
|
131
|
+
ctx.set(defaultValueCtx, markdown);
|
|
132
|
+
ctx.update(remarkStringifyOptionsCtx, (options) => ({ ...options, ...stringify }));
|
|
133
|
+
})
|
|
134
|
+
.use(commonmark)
|
|
135
|
+
.use(gfm)
|
|
136
|
+
.use(remarkSiteBlocks)
|
|
137
|
+
.use(siteBlockSchema)
|
|
138
|
+
.use(remarkTextColors)
|
|
139
|
+
.use(textColorSchema);
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
// The text in parts, for a fixed page's sections (sections.mjs): each block, each heading at the top
|
|
143
|
+
// level ("Overskrift", H2), and the Markdown of the text between them. Empty paragraphs (the lines
|
|
144
|
+
// kept free between two blocks to write in), empty headings (left when one is deleted) and the page's H1
|
|
145
|
+
// (no section's) are left out.
|
|
146
|
+
export function partsOf(ctx) {
|
|
147
|
+
const doc = ctx.get(editorViewCtx).state.doc;
|
|
148
|
+
const serialize = ctx.get(serializerCtx);
|
|
149
|
+
const parts = [];
|
|
150
|
+
let run = [];
|
|
151
|
+
const flush = () => {
|
|
152
|
+
const markdown = run.length ? serialize(doc.type.create(null, run)).trim() : '';
|
|
153
|
+
if (markdown) parts.push({ markdown });
|
|
154
|
+
run = [];
|
|
155
|
+
};
|
|
156
|
+
doc.forEach((node) => {
|
|
157
|
+
// HTML in a section's text stays in its text.
|
|
158
|
+
if (node.type.name === 'siteBlock' && node.attrs.type !== HTML) {
|
|
159
|
+
flush();
|
|
160
|
+
parts.push({ block: { type: node.attrs.type, props: node.attrs.props } });
|
|
161
|
+
} else if (node.type.name === 'heading' && node.attrs.level === 2) {
|
|
162
|
+
flush();
|
|
163
|
+
parts.push({ heading: node.textContent.trim() });
|
|
164
|
+
} else if (node.type.name === 'heading' && node.attrs.level === 1) {
|
|
165
|
+
flush();
|
|
166
|
+
} else if (!((node.type.name === 'paragraph' || node.type.name === 'heading') && !node.textContent.trim() && !node.childCount))
|
|
167
|
+
run.push(node);
|
|
168
|
+
});
|
|
169
|
+
flush();
|
|
170
|
+
return parts;
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
// Keeps a free line (an empty paragraph) between two blocks and before and after them, so there is
|
|
174
|
+
// always a place to write a text between them. Not part of undo. Used by the editor (MarkdownEditor.tsx)
|
|
175
|
+
// and the check, which writes the text back with the free lines in it.
|
|
176
|
+
/** @type {import('@milkdown/kit/utils').$Prose} */
|
|
177
|
+
export const spacing = $prose(
|
|
178
|
+
() =>
|
|
179
|
+
new Plugin({
|
|
180
|
+
appendTransaction: (_, __, state) => {
|
|
181
|
+
const gaps = [];
|
|
182
|
+
let before = null;
|
|
183
|
+
state.doc.forEach((node, at) => {
|
|
184
|
+
if (node.type.name === 'siteBlock' && (!before || before.type.name === 'siteBlock')) gaps.push(at);
|
|
185
|
+
before = node;
|
|
186
|
+
});
|
|
187
|
+
if (state.doc.lastChild?.type.name === 'siteBlock') gaps.push(state.doc.content.size);
|
|
188
|
+
if (!gaps.length) return null;
|
|
189
|
+
const tr = state.tr;
|
|
190
|
+
for (const at of gaps.reverse()) tr.insert(at, state.schema.nodes.paragraph.create());
|
|
191
|
+
return tr.setMeta('addToHistory', false);
|
|
192
|
+
},
|
|
193
|
+
}),
|
|
194
|
+
);
|
|
195
|
+
|
|
196
|
+
// The Markdown of the text, without its empty paragraphs (the free lines between the blocks).
|
|
197
|
+
export function markdownOf(ctx) {
|
|
198
|
+
const doc = ctx.get(editorViewCtx).state.doc;
|
|
199
|
+
const kept = [];
|
|
200
|
+
doc.forEach((node) => {
|
|
201
|
+
if (!(node.type.name === 'paragraph' && node.content.size === 0)) kept.push(node);
|
|
202
|
+
});
|
|
203
|
+
return ctx.get(serializerCtx)(doc.type.create(null, kept));
|
|
204
|
+
}
|