@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
package/pages/[...slug].astro
CHANGED
|
@@ -1,51 +1,51 @@
|
|
|
1
|
-
---
|
|
2
|
-
// Every blog post and imported page lives at a root URL, as on the site it was imported from:
|
|
3
|
-
// blog post src/content/blog/mit-foerste-indlaeg.md -> /mit-foerste-indlaeg/
|
|
4
|
-
// page src/content/pages/ydelser/... -> path from its front matter
|
|
5
|
-
import { render } from 'astro:content';
|
|
6
|
-
import PageLayout from '@theme/layouts/PageLayout.astro';
|
|
7
|
-
import PostLayout from '@theme/layouts/PostLayout.astro';
|
|
8
|
-
import { getPages, getPosts, type Page, type Post } from '@morphemecms/cms/site/content';
|
|
9
|
-
import { standardPaths } from '@morphemecms/cms/site/standardPages';
|
|
10
|
-
|
|
11
|
-
export async function getStaticPaths() {
|
|
12
|
-
const [posts, pages] = await Promise.all([getPosts({ unlisted: true }), getPages()]);
|
|
13
|
-
const seen = new Map<string, string>();
|
|
14
|
-
const claim = (slug: string, source: string) => {
|
|
15
|
-
if (seen.has(slug)) throw new Error(`URL /${slug}/ is used by both ${seen.get(slug)} and ${source}`);
|
|
16
|
-
seen.set(slug, source);
|
|
17
|
-
};
|
|
18
|
-
// The addresses of the pages in packages/editor/pages/ and of the editor, so a page cannot take them.
|
|
19
|
-
for (const slug of ['blog', 'editor', 'ny', '404']) claim(slug, `packages/editor/pages/${slug}`);
|
|
20
|
-
|
|
21
|
-
// The front page is at / (index.astro) and the blog page at /blog/ (blog/index.astro); their own addresses send on there
|
|
22
|
-
// (packages/editor/worker/index.js). The 404 page is the page for an address that does not exist (404.astro), so not at its own.
|
|
23
|
-
const standard = [standardPaths.front, standardPaths.blog, standardPaths.notFound];
|
|
24
|
-
const pageRoutes = pages
|
|
25
|
-
.filter((page) => !standard.includes(page.data.path))
|
|
26
|
-
.map((page) => {
|
|
27
|
-
const slug = page.data.path.replace(/^\/|\/$/g, '');
|
|
28
|
-
claim(slug, `pages/${page.id}`);
|
|
29
|
-
return { params: { slug }, props: { kind: 'page' as const, entry: page } };
|
|
30
|
-
});
|
|
31
|
-
const postRoutes = posts.map((post) => {
|
|
32
|
-
claim(post.id, `blog/${post.id}`);
|
|
33
|
-
return { params: { slug: post.id }, props: { kind: 'post' as const, entry: post } };
|
|
34
|
-
});
|
|
35
|
-
return [...pageRoutes, ...postRoutes];
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
type Props = { kind: 'page'; entry: Page } | { kind: 'post'; entry: Post };
|
|
39
|
-
const props = Astro.props as Props;
|
|
40
|
-
const { Content } = await render(props.entry);
|
|
41
|
-
---
|
|
42
|
-
|
|
43
|
-
{props.kind === 'post' ? (
|
|
44
|
-
<PostLayout post={props.entry}>
|
|
45
|
-
<Content />
|
|
46
|
-
</PostLayout>
|
|
47
|
-
) : (
|
|
48
|
-
<PageLayout page={props.entry}>
|
|
49
|
-
<Content />
|
|
50
|
-
</PageLayout>
|
|
51
|
-
)}
|
|
1
|
+
---
|
|
2
|
+
// Every blog post and imported page lives at a root URL, as on the site it was imported from:
|
|
3
|
+
// blog post src/content/blog/mit-foerste-indlaeg.md -> /mit-foerste-indlaeg/
|
|
4
|
+
// page src/content/pages/ydelser/... -> path from its front matter
|
|
5
|
+
import { render } from 'astro:content';
|
|
6
|
+
import PageLayout from '@theme/layouts/PageLayout.astro';
|
|
7
|
+
import PostLayout from '@theme/layouts/PostLayout.astro';
|
|
8
|
+
import { getPages, getPosts, type Page, type Post } from '@morphemecms/cms/site/content';
|
|
9
|
+
import { standardPaths } from '@morphemecms/cms/site/standardPages';
|
|
10
|
+
|
|
11
|
+
export async function getStaticPaths() {
|
|
12
|
+
const [posts, pages] = await Promise.all([getPosts({ unlisted: true }), getPages()]);
|
|
13
|
+
const seen = new Map<string, string>();
|
|
14
|
+
const claim = (slug: string, source: string) => {
|
|
15
|
+
if (seen.has(slug)) throw new Error(`URL /${slug}/ is used by both ${seen.get(slug)} and ${source}`);
|
|
16
|
+
seen.set(slug, source);
|
|
17
|
+
};
|
|
18
|
+
// The addresses of the pages in packages/editor/pages/ and of the editor, so a page cannot take them.
|
|
19
|
+
for (const slug of ['blog', 'editor', 'ny', '404']) claim(slug, `packages/editor/pages/${slug}`);
|
|
20
|
+
|
|
21
|
+
// The front page is at / (index.astro) and the blog page at /blog/ (blog/index.astro); their own addresses send on there
|
|
22
|
+
// (packages/editor/worker/index.js). The 404 page is the page for an address that does not exist (404.astro), so not at its own.
|
|
23
|
+
const standard = [standardPaths.front, standardPaths.blog, standardPaths.notFound];
|
|
24
|
+
const pageRoutes = pages
|
|
25
|
+
.filter((page) => !standard.includes(page.data.path))
|
|
26
|
+
.map((page) => {
|
|
27
|
+
const slug = page.data.path.replace(/^\/|\/$/g, '');
|
|
28
|
+
claim(slug, `pages/${page.id}`);
|
|
29
|
+
return { params: { slug }, props: { kind: 'page' as const, entry: page } };
|
|
30
|
+
});
|
|
31
|
+
const postRoutes = posts.map((post) => {
|
|
32
|
+
claim(post.id, `blog/${post.id}`);
|
|
33
|
+
return { params: { slug: post.id }, props: { kind: 'post' as const, entry: post } };
|
|
34
|
+
});
|
|
35
|
+
return [...pageRoutes, ...postRoutes];
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
type Props = { kind: 'page'; entry: Page } | { kind: 'post'; entry: Post };
|
|
39
|
+
const props = Astro.props as Props;
|
|
40
|
+
const { Content } = await render(props.entry);
|
|
41
|
+
---
|
|
42
|
+
|
|
43
|
+
{props.kind === 'post' ? (
|
|
44
|
+
<PostLayout post={props.entry}>
|
|
45
|
+
<Content />
|
|
46
|
+
</PostLayout>
|
|
47
|
+
) : (
|
|
48
|
+
<PageLayout page={props.entry}>
|
|
49
|
+
<Content />
|
|
50
|
+
</PageLayout>
|
|
51
|
+
)}
|
package/pages/_headers.txt
CHANGED
|
@@ -1,31 +1,31 @@
|
|
|
1
|
-
# Response headers (Cloudflare reads this file from the assets; on Apache this would be .htaccess).
|
|
2
|
-
# Format: an address (with * for the rest), then its headers, indented, one to a line.
|
|
3
|
-
# They are added to the files and pages from dist/, not to the Worker's own answers (its redirects, /oauth/).
|
|
4
|
-
#
|
|
5
|
-
# Every page and file:
|
|
6
|
-
# - Strict-Transport-Security: always HTTPS, the browser does not try http:// for a year. Not for the
|
|
7
|
-
# subdomains (no includeSubDomains), so another service on a subdomain is not affected.
|
|
8
|
-
# - X-Content-Type-Options: a file is what its content-type says, nothing else.
|
|
9
|
-
# - Referrer-Policy: other sites see only the domain a visitor came from, not the address of the page.
|
|
10
|
-
# - X-Frame-Options: no other site can show the pages in a frame (Calendly and YouTube are shown in the
|
|
11
|
-
# site, not the other way round).
|
|
12
|
-
# - Permissions-Policy: camera, microphone and location are never used, also not by Calendly or YouTube.
|
|
13
|
-
# The Content-Security-Policy is in each page itself (a <meta> the build writes: packages/editor/lib/csp.mjs),
|
|
14
|
-
# since it names the page's own scripts by their hashes.
|
|
15
|
-
/*
|
|
16
|
-
Strict-Transport-Security: max-age=31536000
|
|
17
|
-
X-Content-Type-Options: nosniff
|
|
18
|
-
Referrer-Policy: strict-origin-when-cross-origin
|
|
19
|
-
X-Frame-Options: SAMEORIGIN
|
|
20
|
-
Permissions-Policy: camera=(), microphone=(), geolocation=()
|
|
21
|
-
|
|
22
|
-
# An SVG file opened on its own (the logo, the favicon) is a page on the site's address, without the <meta> CSP the
|
|
23
|
-
# pages have. Its own CSP lets it draw (its own CSS, a picture inside it as data:) and nothing else: no script runs,
|
|
24
|
-
# nothing is loaded from elsewhere, and it is sandboxed, so it is never the site's address. The logo is also cleaned
|
|
25
|
-
# when it is picked (cleanSvg in packages/editor/lib/svg.mjs); this holds for any SVG in the build.
|
|
26
|
-
/*.svg
|
|
27
|
-
Content-Security-Policy: default-src 'none'; style-src 'unsafe-inline'; img-src data:; sandbox
|
|
28
|
-
|
|
29
|
-
# Scripts and fonts from the build get a new name whenever they change, so they can be kept for a year.
|
|
30
|
-
/_astro/*
|
|
31
|
-
Cache-Control: public, max-age=31536000, immutable
|
|
1
|
+
# Response headers (Cloudflare reads this file from the assets; on Apache this would be .htaccess).
|
|
2
|
+
# Format: an address (with * for the rest), then its headers, indented, one to a line.
|
|
3
|
+
# They are added to the files and pages from dist/, not to the Worker's own answers (its redirects, /oauth/).
|
|
4
|
+
#
|
|
5
|
+
# Every page and file:
|
|
6
|
+
# - Strict-Transport-Security: always HTTPS, the browser does not try http:// for a year. Not for the
|
|
7
|
+
# subdomains (no includeSubDomains), so another service on a subdomain is not affected.
|
|
8
|
+
# - X-Content-Type-Options: a file is what its content-type says, nothing else.
|
|
9
|
+
# - Referrer-Policy: other sites see only the domain a visitor came from, not the address of the page.
|
|
10
|
+
# - X-Frame-Options: no other site can show the pages in a frame (Calendly and YouTube are shown in the
|
|
11
|
+
# site, not the other way round).
|
|
12
|
+
# - Permissions-Policy: camera, microphone and location are never used, also not by Calendly or YouTube.
|
|
13
|
+
# The Content-Security-Policy is in each page itself (a <meta> the build writes: packages/editor/lib/csp.mjs),
|
|
14
|
+
# since it names the page's own scripts by their hashes.
|
|
15
|
+
/*
|
|
16
|
+
Strict-Transport-Security: max-age=31536000
|
|
17
|
+
X-Content-Type-Options: nosniff
|
|
18
|
+
Referrer-Policy: strict-origin-when-cross-origin
|
|
19
|
+
X-Frame-Options: SAMEORIGIN
|
|
20
|
+
Permissions-Policy: camera=(), microphone=(), geolocation=()
|
|
21
|
+
|
|
22
|
+
# An SVG file opened on its own (the logo, the favicon) is a page on the site's address, without the <meta> CSP the
|
|
23
|
+
# pages have. Its own CSP lets it draw (its own CSS, a picture inside it as data:) and nothing else: no script runs,
|
|
24
|
+
# nothing is loaded from elsewhere, and it is sandboxed, so it is never the site's address. The logo is also cleaned
|
|
25
|
+
# when it is picked (cleanSvg in packages/editor/lib/svg.mjs); this holds for any SVG in the build.
|
|
26
|
+
/*.svg
|
|
27
|
+
Content-Security-Policy: default-src 'none'; style-src 'unsafe-inline'; img-src data:; sandbox
|
|
28
|
+
|
|
29
|
+
# Scripts and fonts from the build get a new name whenever they change, so they can be kept for a year.
|
|
30
|
+
/_astro/*
|
|
31
|
+
Cache-Control: public, max-age=31536000, immutable
|
package/pages/blog/index.astro
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
---
|
|
2
|
-
// The blog: the page chosen as the blog page (packages/editor/site/standardPages.ts), drawn by the theme
|
|
3
|
-
// (src/themes/<theme>/templates/Blog.astro).
|
|
4
|
-
import Blog from '@theme/templates/Blog.astro';
|
|
5
|
-
import { blogPage } from '@morphemecms/cms/site/standardPages';
|
|
6
|
-
|
|
7
|
-
const page = await blogPage();
|
|
8
|
-
---
|
|
9
|
-
|
|
10
|
-
<Blog {...page} />
|
|
1
|
+
---
|
|
2
|
+
// The blog: the page chosen as the blog page (packages/editor/site/standardPages.ts), drawn by the theme
|
|
3
|
+
// (src/themes/<theme>/templates/Blog.astro).
|
|
4
|
+
import Blog from '@theme/templates/Blog.astro';
|
|
5
|
+
import { blogPage } from '@morphemecms/cms/site/standardPages';
|
|
6
|
+
|
|
7
|
+
const page = await blogPage();
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
<Blog {...page} />
|
|
@@ -1,18 +1,18 @@
|
|
|
1
|
-
---
|
|
2
|
-
// A tag's page on the blog, drawn by the theme (src/themes/<theme>/templates/Category.astro).
|
|
3
|
-
import Category from '@theme/templates/Category.astro';
|
|
4
|
-
import { getCategories, getPosts } from '@morphemecms/cms/site/content';
|
|
5
|
-
|
|
6
|
-
export async function getStaticPaths() {
|
|
7
|
-
const [categories, posts] = await Promise.all([getCategories(), getPosts()]);
|
|
8
|
-
return categories.map((c) => ({
|
|
9
|
-
params: { category: c.slug },
|
|
10
|
-
props: { name: c.name, posts: posts.filter((p) => p.data.categories.includes(c.slug)) },
|
|
11
|
-
}));
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
const { category } = Astro.params;
|
|
15
|
-
const { name, posts } = Astro.props;
|
|
16
|
-
---
|
|
17
|
-
|
|
18
|
-
<Category category={category} name={name} posts={posts} />
|
|
1
|
+
---
|
|
2
|
+
// A tag's page on the blog, drawn by the theme (src/themes/<theme>/templates/Category.astro).
|
|
3
|
+
import Category from '@theme/templates/Category.astro';
|
|
4
|
+
import { getCategories, getPosts } from '@morphemecms/cms/site/content';
|
|
5
|
+
|
|
6
|
+
export async function getStaticPaths() {
|
|
7
|
+
const [categories, posts] = await Promise.all([getCategories(), getPosts()]);
|
|
8
|
+
return categories.map((c) => ({
|
|
9
|
+
params: { category: c.slug },
|
|
10
|
+
props: { name: c.name, posts: posts.filter((p) => p.data.categories.includes(c.slug)) },
|
|
11
|
+
}));
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
const { category } = Astro.params;
|
|
15
|
+
const { name, posts } = Astro.props;
|
|
16
|
+
---
|
|
17
|
+
|
|
18
|
+
<Category category={category} name={name} posts={posts} />
|
|
@@ -1,25 +1,25 @@
|
|
|
1
|
-
// /editor/code-images.json: the uploaded pictures (/images/uploads/…) the site's own code uses (src/: its themes, apps
|
|
2
|
-
// and config, e.g. the portrait in src/site/config.ts), not in the texts the editor has. "Filer" counts them as in use
|
|
3
|
-
// and does not offer to delete them (packages/editor/src/Media.tsx).
|
|
4
|
-
import fs from 'node:fs';
|
|
5
|
-
import path from 'node:path';
|
|
6
|
-
|
|
7
|
-
// The site's own code, from its root (the working directory).
|
|
8
|
-
const SRC = `${path.resolve('src')}/`;
|
|
9
|
-
// The texts are not the site's code; the editor reads them itself (and is not in src/).
|
|
10
|
-
const SKIP = ['content', 'data/image-manifest.json'];
|
|
11
|
-
const CODE = /\.(astro|ts|tsx|js|mjs|css)$/;
|
|
12
|
-
const ADDRESS = /\/images\/uploads\/[^\s'"`)<>,]+\.(?:webp|jpe?g|png|gif|svg|avif)/gi;
|
|
13
|
-
|
|
14
|
-
function walk(dir) {
|
|
15
|
-
return fs.readdirSync(dir, { withFileTypes: true }).flatMap((e) => {
|
|
16
|
-
const file = path.join(dir, e.name);
|
|
17
|
-
if (SKIP.includes(path.relative(SRC, file))) return [];
|
|
18
|
-
return e.isDirectory() ? walk(file) : CODE.test(e.name) ? [file] : [];
|
|
19
|
-
});
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
export function GET() {
|
|
23
|
-
const used = new Set(walk(SRC).flatMap((file) => fs.readFileSync(file, 'utf8').match(ADDRESS) ?? []));
|
|
24
|
-
return new Response(JSON.stringify([...used].sort()));
|
|
25
|
-
}
|
|
1
|
+
// /editor/code-images.json: the uploaded pictures (/images/uploads/…) the site's own code uses (src/: its themes, apps
|
|
2
|
+
// and config, e.g. the portrait in src/site/config.ts), not in the texts the editor has. "Filer" counts them as in use
|
|
3
|
+
// and does not offer to delete them (packages/editor/src/Media.tsx).
|
|
4
|
+
import fs from 'node:fs';
|
|
5
|
+
import path from 'node:path';
|
|
6
|
+
|
|
7
|
+
// The site's own code, from its root (the working directory).
|
|
8
|
+
const SRC = `${path.resolve('src')}/`;
|
|
9
|
+
// The texts are not the site's code; the editor reads them itself (and is not in src/).
|
|
10
|
+
const SKIP = ['content', 'data/image-manifest.json'];
|
|
11
|
+
const CODE = /\.(astro|ts|tsx|js|mjs|css)$/;
|
|
12
|
+
const ADDRESS = /\/images\/uploads\/[^\s'"`)<>,]+\.(?:webp|jpe?g|png|gif|svg|avif)/gi;
|
|
13
|
+
|
|
14
|
+
function walk(dir) {
|
|
15
|
+
return fs.readdirSync(dir, { withFileTypes: true }).flatMap((e) => {
|
|
16
|
+
const file = path.join(dir, e.name);
|
|
17
|
+
if (SKIP.includes(path.relative(SRC, file))) return [];
|
|
18
|
+
return e.isDirectory() ? walk(file) : CODE.test(e.name) ? [file] : [];
|
|
19
|
+
});
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export function GET() {
|
|
23
|
+
const used = new Set(walk(SRC).flatMap((file) => fs.readFileSync(file, 'utf8').match(ADDRESS) ?? []));
|
|
24
|
+
return new Response(JSON.stringify([...used].sort()));
|
|
25
|
+
}
|
package/pages/editor/index.astro
CHANGED
|
@@ -1,75 +1,75 @@
|
|
|
1
|
-
---
|
|
2
|
-
// The editor (packages/editor/src/, docs/editor.md). A bare page in the site's style: no menu, footer,
|
|
3
|
-
// cookie banner or tracking, and not in the sitemap or in search engines. It can be installed as an
|
|
4
|
-
// app (/editor/manifest.webmanifest, packages/editor/pages/editor/manifest.webmanifest.js; icons from
|
|
5
|
-
// packages/editor/scripts/editor-icons.mjs) and then opens
|
|
6
|
-
// without the browser's bars. viewport-fit=cover: the app keeps clear of a phone's notch and home bar
|
|
7
|
-
// itself (safe-area padding). interactive-widget=resizes-content: on Android the page gets shorter when
|
|
8
|
-
// the keyboard opens, so the top bar and the text toolbar stay in view while typing. maximum-scale=1
|
|
9
|
-
// (and touch-action in editor.css): no zooming in by a pinch or a double tap, which in Chrome on
|
|
10
|
-
// Android pushes the bar with "Gem ændringer" out of sight below the screen.
|
|
11
|
-
// The manifest has no colours on purpose: Chrome on Android paints the installed app's navigation bar
|
|
12
|
-
// (the strip at the bottom of the screen) in them, and one colour cannot fit both light and dark mode.
|
|
13
|
-
// Without them the bar follows the phone's own light or dark mode; the top bar follows the
|
|
14
|
-
// theme-color tags below.
|
|
15
|
-
// editor-version: the fingerprint of this editor's code, also in /editor/version.json; an editor
|
|
16
|
-
// left open reloads itself when the two differ (packages/editor/src/deploy.ts).
|
|
17
|
-
import '@theme/styles/global.css';
|
|
18
|
-
import App from '@morphemecms/cms/src/App.tsx';
|
|
19
|
-
import { editorVersion } from '@morphemecms/cms/site/editor-version.mjs';
|
|
20
|
-
import { config } from '@site/config';
|
|
21
|
-
// The site's colours (the theme's styles/global.css); the editor puts the ones it has loaded in their place, so
|
|
22
|
-
// a change under "Farver" shows at once (packages/editor/src/theme.ts).
|
|
23
|
-
// With those a file written before them does not have made (completeColors).
|
|
24
|
-
import colors from '@data/colors.json';
|
|
25
|
-
import { colorsCss } from '@morphemecms/cms/lib/colors';
|
|
26
|
-
import { completeColors } from '@morphemecms/cms/lib/dynamic-colors';
|
|
27
|
-
import { colorRoles } from '@site/colors';
|
|
28
|
-
// How the site moves, which the editor moves by too (packages/editor/lib/motion.ts); the editor puts a new choice under
|
|
29
|
-
// "Bevægelse" in its place at once (packages/editor/src/theme.ts).
|
|
30
|
-
import { motionCss } from '@morphemecms/cms/lib/motion';
|
|
31
|
-
import { motionScheme } from '@morphemecms/cms/site/motion';
|
|
32
|
-
---
|
|
33
|
-
|
|
34
|
-
<!doctype html>
|
|
35
|
-
<html lang={config.locale} data-motion-scheme={motionScheme}>
|
|
36
|
-
<head>
|
|
37
|
-
<meta charset="utf-8" />
|
|
38
|
-
<meta
|
|
39
|
-
name="viewport"
|
|
40
|
-
content="width=device-width, initial-scale=1, maximum-scale=1, viewport-fit=cover, interactive-widget=resizes-content"
|
|
41
|
-
/>
|
|
42
|
-
<meta name="robots" content="noindex, nofollow" />
|
|
43
|
-
<meta name="editor-version" content={editorVersion()} />
|
|
44
|
-
<link rel="icon" href="/favicon.svg" type="image/svg+xml" />
|
|
45
|
-
<link rel="manifest" href="/editor/manifest.webmanifest" />
|
|
46
|
-
<link rel="apple-touch-icon" href="/editor/apple-touch-icon.png" />
|
|
47
|
-
<meta name="mobile-web-app-capable" content="yes" />
|
|
48
|
-
<meta name="apple-mobile-web-app-capable" content="yes" />
|
|
49
|
-
<meta name="apple-mobile-web-app-title" content={config.name} />
|
|
50
|
-
<meta name="apple-mobile-web-app-status-bar-style" content="default" />
|
|
51
|
-
<!-- The top bar in the background's colour, the screens' own and the app bar's at the top; data-color: that of its
|
|
52
|
-
own mode, for a picked one. -->
|
|
53
|
-
<meta name="theme-color" content={colors.light.bg} data-color={colors.light.bg} media="(prefers-color-scheme: light)" />
|
|
54
|
-
<meta name="theme-color" content={colors.dark.bg} data-color={colors.dark.bg} media="(prefers-color-scheme: dark)" />
|
|
55
|
-
<style id="site-colors" is:inline set:html={colorsCss(completeColors(colors, colorRoles))}></style>
|
|
56
|
-
<style id="site-motion" is:inline set:html={motionCss(motionScheme)}></style>
|
|
57
|
-
<!-- Light or dark as picked on "Konto" (packages/editor/src/theme.ts), before the page is drawn. The
|
|
58
|
-
language (lang) is the site's until the editor has picked its own (packages/editor/src/i18n/). -->
|
|
59
|
-
<script is:inline>
|
|
60
|
-
try {
|
|
61
|
-
const theme = localStorage.getItem('editor-theme');
|
|
62
|
-
if (theme === 'light' || theme === 'dark') {
|
|
63
|
-
document.documentElement.dataset.theme = theme;
|
|
64
|
-
const metas = [...document.querySelectorAll('meta[name="theme-color"]')];
|
|
65
|
-
const own = metas.find((m) => m.media.includes('dark') === (theme === 'dark'));
|
|
66
|
-
for (const m of metas) m.content = own.dataset.color;
|
|
67
|
-
}
|
|
68
|
-
} catch {}
|
|
69
|
-
</script>
|
|
70
|
-
<title>{config.name}</title>
|
|
71
|
-
</head>
|
|
72
|
-
<body>
|
|
73
|
-
<App client:only="react" />
|
|
74
|
-
</body>
|
|
75
|
-
</html>
|
|
1
|
+
---
|
|
2
|
+
// The editor (packages/editor/src/, docs/editor.md). A bare page in the site's style: no menu, footer,
|
|
3
|
+
// cookie banner or tracking, and not in the sitemap or in search engines. It can be installed as an
|
|
4
|
+
// app (/editor/manifest.webmanifest, packages/editor/pages/editor/manifest.webmanifest.js; icons from
|
|
5
|
+
// packages/editor/scripts/editor-icons.mjs) and then opens
|
|
6
|
+
// without the browser's bars. viewport-fit=cover: the app keeps clear of a phone's notch and home bar
|
|
7
|
+
// itself (safe-area padding). interactive-widget=resizes-content: on Android the page gets shorter when
|
|
8
|
+
// the keyboard opens, so the top bar and the text toolbar stay in view while typing. maximum-scale=1
|
|
9
|
+
// (and touch-action in editor.css): no zooming in by a pinch or a double tap, which in Chrome on
|
|
10
|
+
// Android pushes the bar with "Gem ændringer" out of sight below the screen.
|
|
11
|
+
// The manifest has no colours on purpose: Chrome on Android paints the installed app's navigation bar
|
|
12
|
+
// (the strip at the bottom of the screen) in them, and one colour cannot fit both light and dark mode.
|
|
13
|
+
// Without them the bar follows the phone's own light or dark mode; the top bar follows the
|
|
14
|
+
// theme-color tags below.
|
|
15
|
+
// editor-version: the fingerprint of this editor's code, also in /editor/version.json; an editor
|
|
16
|
+
// left open reloads itself when the two differ (packages/editor/src/deploy.ts).
|
|
17
|
+
import '@theme/styles/global.css';
|
|
18
|
+
import App from '@morphemecms/cms/src/App.tsx';
|
|
19
|
+
import { editorVersion } from '@morphemecms/cms/site/editor-version.mjs';
|
|
20
|
+
import { config } from '@site/config';
|
|
21
|
+
// The site's colours (the theme's styles/global.css); the editor puts the ones it has loaded in their place, so
|
|
22
|
+
// a change under "Farver" shows at once (packages/editor/src/theme.ts).
|
|
23
|
+
// With those a file written before them does not have made (completeColors).
|
|
24
|
+
import colors from '@data/colors.json';
|
|
25
|
+
import { colorsCss } from '@morphemecms/cms/lib/colors';
|
|
26
|
+
import { completeColors } from '@morphemecms/cms/lib/dynamic-colors';
|
|
27
|
+
import { colorRoles } from '@site/colors';
|
|
28
|
+
// How the site moves, which the editor moves by too (packages/editor/lib/motion.ts); the editor puts a new choice under
|
|
29
|
+
// "Bevægelse" in its place at once (packages/editor/src/theme.ts).
|
|
30
|
+
import { motionCss } from '@morphemecms/cms/lib/motion';
|
|
31
|
+
import { motionScheme } from '@morphemecms/cms/site/motion';
|
|
32
|
+
---
|
|
33
|
+
|
|
34
|
+
<!doctype html>
|
|
35
|
+
<html lang={config.locale} data-motion-scheme={motionScheme}>
|
|
36
|
+
<head>
|
|
37
|
+
<meta charset="utf-8" />
|
|
38
|
+
<meta
|
|
39
|
+
name="viewport"
|
|
40
|
+
content="width=device-width, initial-scale=1, maximum-scale=1, viewport-fit=cover, interactive-widget=resizes-content"
|
|
41
|
+
/>
|
|
42
|
+
<meta name="robots" content="noindex, nofollow" />
|
|
43
|
+
<meta name="editor-version" content={editorVersion()} />
|
|
44
|
+
<link rel="icon" href="/favicon.svg" type="image/svg+xml" />
|
|
45
|
+
<link rel="manifest" href="/editor/manifest.webmanifest" />
|
|
46
|
+
<link rel="apple-touch-icon" href="/editor/apple-touch-icon.png" />
|
|
47
|
+
<meta name="mobile-web-app-capable" content="yes" />
|
|
48
|
+
<meta name="apple-mobile-web-app-capable" content="yes" />
|
|
49
|
+
<meta name="apple-mobile-web-app-title" content={config.name} />
|
|
50
|
+
<meta name="apple-mobile-web-app-status-bar-style" content="default" />
|
|
51
|
+
<!-- The top bar in the background's colour, the screens' own and the app bar's at the top; data-color: that of its
|
|
52
|
+
own mode, for a picked one. -->
|
|
53
|
+
<meta name="theme-color" content={colors.light.bg} data-color={colors.light.bg} media="(prefers-color-scheme: light)" />
|
|
54
|
+
<meta name="theme-color" content={colors.dark.bg} data-color={colors.dark.bg} media="(prefers-color-scheme: dark)" />
|
|
55
|
+
<style id="site-colors" is:inline set:html={colorsCss(completeColors(colors, colorRoles))}></style>
|
|
56
|
+
<style id="site-motion" is:inline set:html={motionCss(motionScheme)}></style>
|
|
57
|
+
<!-- Light or dark as picked on "Konto" (packages/editor/src/theme.ts), before the page is drawn. The
|
|
58
|
+
language (lang) is the site's until the editor has picked its own (packages/editor/src/i18n/). -->
|
|
59
|
+
<script is:inline>
|
|
60
|
+
try {
|
|
61
|
+
const theme = localStorage.getItem('editor-theme');
|
|
62
|
+
if (theme === 'light' || theme === 'dark') {
|
|
63
|
+
document.documentElement.dataset.theme = theme;
|
|
64
|
+
const metas = [...document.querySelectorAll('meta[name="theme-color"]')];
|
|
65
|
+
const own = metas.find((m) => m.media.includes('dark') === (theme === 'dark'));
|
|
66
|
+
for (const m of metas) m.content = own.dataset.color;
|
|
67
|
+
}
|
|
68
|
+
} catch {}
|
|
69
|
+
</script>
|
|
70
|
+
<title>{config.name}</title>
|
|
71
|
+
</head>
|
|
72
|
+
<body>
|
|
73
|
+
<App client:only="react" />
|
|
74
|
+
</body>
|
|
75
|
+
</html>
|
|
@@ -1,23 +1,23 @@
|
|
|
1
|
-
// /editor/manifest.webmanifest: the editor as an app on a phone's home screen or a computer, with the
|
|
2
|
-
// site's name, description and language for it (src/site/config.ts) and the icons from
|
|
3
|
-
// packages/editor/scripts/editor-icons.mjs. No colours, on purpose (packages/editor/pages/editor/index.astro).
|
|
4
|
-
import { config } from '@site/config';
|
|
5
|
-
|
|
6
|
-
export function GET() {
|
|
7
|
-
return new Response(`{
|
|
8
|
-
"name": ${JSON.stringify(config.name)},
|
|
9
|
-
"short_name": ${JSON.stringify(config.name)},
|
|
10
|
-
"description": ${JSON.stringify(config.description)},
|
|
11
|
-
"lang": ${JSON.stringify(config.locale)},
|
|
12
|
-
"id": "/editor/",
|
|
13
|
-
"start_url": "/editor/",
|
|
14
|
-
"scope": "/editor/",
|
|
15
|
-
"display": "standalone",
|
|
16
|
-
"icons": [
|
|
17
|
-
{ "src": "/editor/icon-192.png", "sizes": "192x192", "type": "image/png" },
|
|
18
|
-
{ "src": "/editor/icon-512.png", "sizes": "512x512", "type": "image/png" },
|
|
19
|
-
{ "src": "/editor/icon-maskable-512.png", "sizes": "512x512", "type": "image/png", "purpose": "maskable" }
|
|
20
|
-
]
|
|
21
|
-
}
|
|
22
|
-
`);
|
|
23
|
-
}
|
|
1
|
+
// /editor/manifest.webmanifest: the editor as an app on a phone's home screen or a computer, with the
|
|
2
|
+
// site's name, description and language for it (src/site/config.ts) and the icons from
|
|
3
|
+
// packages/editor/scripts/editor-icons.mjs. No colours, on purpose (packages/editor/pages/editor/index.astro).
|
|
4
|
+
import { config } from '@site/config';
|
|
5
|
+
|
|
6
|
+
export function GET() {
|
|
7
|
+
return new Response(`{
|
|
8
|
+
"name": ${JSON.stringify(config.name)},
|
|
9
|
+
"short_name": ${JSON.stringify(config.name)},
|
|
10
|
+
"description": ${JSON.stringify(config.description)},
|
|
11
|
+
"lang": ${JSON.stringify(config.locale)},
|
|
12
|
+
"id": "/editor/",
|
|
13
|
+
"start_url": "/editor/",
|
|
14
|
+
"scope": "/editor/",
|
|
15
|
+
"display": "standalone",
|
|
16
|
+
"icons": [
|
|
17
|
+
{ "src": "/editor/icon-192.png", "sizes": "192x192", "type": "image/png" },
|
|
18
|
+
{ "src": "/editor/icon-512.png", "sizes": "512x512", "type": "image/png" },
|
|
19
|
+
{ "src": "/editor/icon-maskable-512.png", "sizes": "512x512", "type": "image/png", "purpose": "maskable" }
|
|
20
|
+
]
|
|
21
|
+
}
|
|
22
|
+
`);
|
|
23
|
+
}
|
package/pages/editor/sw.js
CHANGED
|
@@ -1,33 +1,33 @@
|
|
|
1
|
-
// The editor's service worker, only for its notifications on the phone or computer (packages/editor/src/
|
|
2
|
-
// while the editor is open but not on screen, it shows them (on Android that works only through a service worker), and
|
|
3
|
-
// when the site's Worker sends one (Web Push, packages/editor/worker/push.js: the site is updated after a save, an app's notification),
|
|
4
|
-
// the browser wakes it, also when the editor is closed, and it shows that. It does not cache or touch any request.
|
|
5
|
-
// Tapping a notification brings the editor to the front, on the screen it is about.
|
|
6
|
-
self.addEventListener('push', (event) => {
|
|
7
|
-
let data = {};
|
|
8
|
-
try {
|
|
9
|
-
data = event.data?.json() ?? {};
|
|
10
|
-
} catch {}
|
|
11
|
-
event.waitUntil(
|
|
12
|
-
self.registration.showNotification(data.title || 'Editor', {
|
|
13
|
-
body: data.body ?? '',
|
|
14
|
-
icon: '/editor/icon-192.png',
|
|
15
|
-
tag: data.tag || 'site',
|
|
16
|
-
data: { to: data.to },
|
|
17
|
-
}),
|
|
18
|
-
);
|
|
19
|
-
});
|
|
20
|
-
|
|
21
|
-
self.addEventListener('notificationclick', (event) => {
|
|
22
|
-
event.notification.close();
|
|
23
|
-
const to = event.notification.data?.to;
|
|
24
|
-
const url = `/editor/${to ? `#${to}` : ''}`;
|
|
25
|
-
event.waitUntil(
|
|
26
|
-
self.clients.matchAll({ type: 'window' }).then((open) => {
|
|
27
|
-
if (!open.length) return self.clients.openWindow(url);
|
|
28
|
-
// The open editor goes there itself (App.tsx), so a form with changes asks first.
|
|
29
|
-
if (to) open[0].postMessage({ to });
|
|
30
|
-
return open[0].focus();
|
|
31
|
-
}),
|
|
32
|
-
);
|
|
33
|
-
});
|
|
1
|
+
// The editor's service worker, only for its notifications on the phone or computer (packages/editor/src/notificationData.ts):
|
|
2
|
+
// while the editor is open but not on screen, it shows them (on Android that works only through a service worker), and
|
|
3
|
+
// when the site's Worker sends one (Web Push, packages/editor/worker/push.js: the site is updated after a save, an app's notification),
|
|
4
|
+
// the browser wakes it, also when the editor is closed, and it shows that. It does not cache or touch any request.
|
|
5
|
+
// Tapping a notification brings the editor to the front, on the screen it is about.
|
|
6
|
+
self.addEventListener('push', (event) => {
|
|
7
|
+
let data = {};
|
|
8
|
+
try {
|
|
9
|
+
data = event.data?.json() ?? {};
|
|
10
|
+
} catch {}
|
|
11
|
+
event.waitUntil(
|
|
12
|
+
self.registration.showNotification(data.title || 'Editor', {
|
|
13
|
+
body: data.body ?? '',
|
|
14
|
+
icon: '/editor/icon-192.png',
|
|
15
|
+
tag: data.tag || 'site',
|
|
16
|
+
data: { to: data.to },
|
|
17
|
+
}),
|
|
18
|
+
);
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
self.addEventListener('notificationclick', (event) => {
|
|
22
|
+
event.notification.close();
|
|
23
|
+
const to = event.notification.data?.to;
|
|
24
|
+
const url = `/editor/${to ? `#${to}` : ''}`;
|
|
25
|
+
event.waitUntil(
|
|
26
|
+
self.clients.matchAll({ type: 'window' }).then((open) => {
|
|
27
|
+
if (!open.length) return self.clients.openWindow(url);
|
|
28
|
+
// The open editor goes there itself (App.tsx), so a form with changes asks first.
|
|
29
|
+
if (to) open[0].postMessage({ to });
|
|
30
|
+
return open[0].focus();
|
|
31
|
+
}),
|
|
32
|
+
);
|
|
33
|
+
});
|
package/pages/editor/sw.js.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
// /editor/sw.js: the editor's service worker (sw.js), for its notifications.
|
|
2
|
-
import code from './sw.js?raw';
|
|
3
|
-
|
|
4
|
-
export const GET = () => new Response(code, { headers: { 'content-type': 'text/javascript' } });
|
|
1
|
+
// /editor/sw.js: the editor's service worker (sw.js), for its notifications.
|
|
2
|
+
import code from './sw.js?raw';
|
|
3
|
+
|
|
4
|
+
export const GET = () => new Response(code, { headers: { 'content-type': 'text/javascript' } });
|
|
@@ -1,21 +1,21 @@
|
|
|
1
|
-
// /editor/thumbnails.json: for each uploaded picture (/images/uploads/…), its 480 px wide copy
|
|
2
|
-
// (/images/_r/…, made by packages/editor/scripts/responsive-images.mjs before the build), which the grid in "Filer"
|
|
3
|
-
// shows instead of the picture itself (packages/editor/src/Media.tsx). A picture without one (it is
|
|
4
|
-
// smaller) is not in it, and the grid shows the picture.
|
|
5
|
-
import fs from 'node:fs';
|
|
6
|
-
import path from 'node:path';
|
|
7
|
-
|
|
8
|
-
// From where the build runs, as packages/editor/site/images.mjs (this file is bundled elsewhere first).
|
|
9
|
-
const MANIFEST = path.resolve('src/data/image-manifest.json');
|
|
10
|
-
const WIDTH = 480;
|
|
11
|
-
|
|
12
|
-
export function GET() {
|
|
13
|
-
const manifest = fs.existsSync(MANIFEST) ? JSON.parse(fs.readFileSync(MANIFEST, 'utf8')) : {};
|
|
14
|
-
const thumbnails = Object.fromEntries(
|
|
15
|
-
Object.entries(manifest).flatMap(([src, { variants }]) => {
|
|
16
|
-
const small = variants.find((v) => v.w === WIDTH);
|
|
17
|
-
return small ? [[src, small.src]] : [];
|
|
18
|
-
}),
|
|
19
|
-
);
|
|
20
|
-
return new Response(JSON.stringify(thumbnails));
|
|
21
|
-
}
|
|
1
|
+
// /editor/thumbnails.json: for each uploaded picture (/images/uploads/…), its 480 px wide copy
|
|
2
|
+
// (/images/_r/…, made by packages/editor/scripts/responsive-images.mjs before the build), which the grid in "Filer"
|
|
3
|
+
// shows instead of the picture itself (packages/editor/src/Media.tsx). A picture without one (it is
|
|
4
|
+
// smaller) is not in it, and the grid shows the picture.
|
|
5
|
+
import fs from 'node:fs';
|
|
6
|
+
import path from 'node:path';
|
|
7
|
+
|
|
8
|
+
// From where the build runs, as packages/editor/site/images.mjs (this file is bundled elsewhere first).
|
|
9
|
+
const MANIFEST = path.resolve('src/data/image-manifest.json');
|
|
10
|
+
const WIDTH = 480;
|
|
11
|
+
|
|
12
|
+
export function GET() {
|
|
13
|
+
const manifest = fs.existsSync(MANIFEST) ? JSON.parse(fs.readFileSync(MANIFEST, 'utf8')) : {};
|
|
14
|
+
const thumbnails = Object.fromEntries(
|
|
15
|
+
Object.entries(manifest).flatMap(([src, { variants }]) => {
|
|
16
|
+
const small = variants.find((v) => v.w === WIDTH);
|
|
17
|
+
return small ? [[src, small.src]] : [];
|
|
18
|
+
}),
|
|
19
|
+
);
|
|
20
|
+
return new Response(JSON.stringify(thumbnails));
|
|
21
|
+
}
|