@rathnasgala2/template 3.2.1 → 4.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +17 -13
- package/contracts/theme-styling-contract.jcs +1 -1
- package/package.json +4 -2
- package/src/core/index.js +25 -17
- package/src/core/internal/appearance/base-layer.js +16 -2
- package/src/core/internal/appearance/styling-contract.js +24 -3
- package/src/core/internal/chrome.js +41 -13
- package/src/core/internal/eleventy-render.js +1 -1
- package/src/core/internal/page-kinds.js +131 -25
- package/src/core/internal/template-composition.js +185 -0
- package/src/core/internal/theme-assets.js +18 -3
package/README.md
CHANGED
|
@@ -629,7 +629,7 @@ npm run verify
|
|
|
629
629
|
hand-maintained) runs, in order: Prettier format check, ESLint,
|
|
630
630
|
`tsc --checkJs --noEmit`, the dependency-cruiser
|
|
631
631
|
architecture/module-tree-absence gate, `jscpd` duplication scan, the
|
|
632
|
-
`contracts/*.jcs` canonical-form check, the no-local-schema-pin check,
|
|
632
|
+
`contracts/*.jcs` canonical-form check, the no-local-schema-pin check, the
|
|
633
633
|
`node --test`, the license inventory check, the SBOM currency check
|
|
634
634
|
(`sbom:check` compares `sbom.cdx.json` against the current lockfile — it is not
|
|
635
635
|
a presence check), the workflow-pin check, and `npm audit --audit-level=high`.
|
|
@@ -645,7 +645,7 @@ npm run architecture # dependency-cruiser: core never imports src/modules, no
|
|
|
645
645
|
npm run duplication # jscpd, 3% / 50 tokens
|
|
646
646
|
npm run contracts:generate # (re)write contracts/*.jcs from their reviewed source modules
|
|
647
647
|
npm run contracts:check # fail if committed contracts drifted
|
|
648
|
-
npm run schema-pin:check #
|
|
648
|
+
npm run schema-pin:check # require the exact registry @rathnasgala2/schemas release
|
|
649
649
|
npm test # node --test
|
|
650
650
|
npm run licenses:generate # (re)write THIRD_PARTY_LICENSES.json
|
|
651
651
|
npm run licenses:check # fail if it drifted from package-lock.json
|
|
@@ -656,6 +656,11 @@ npm run workflows:drift # fail if workflow files diverge from their own base
|
|
|
656
656
|
npm run audit # npm audit --audit-level=high
|
|
657
657
|
```
|
|
658
658
|
|
|
659
|
+
Source development does not require a sibling schema checkout. The exact
|
|
660
|
+
`@rathnasgala2/schemas@3.8.0` release is installed from the npm registry, and
|
|
661
|
+
the lockfile carries its registry integrity. The exact peer is the public
|
|
662
|
+
consumer contract.
|
|
663
|
+
|
|
659
664
|
## Package layout
|
|
660
665
|
|
|
661
666
|
```text
|
|
@@ -679,17 +684,16 @@ editions: they are a rendered content kind (see Editions).
|
|
|
679
684
|
|
|
680
685
|
## Consuming `@rathnasgala2/schemas`
|
|
681
686
|
|
|
682
|
-
This
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
2.
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
copy, the `PrincipalSummary`/`AuthenticatorSummary`/keyset field additions) are
|
|
687
|
+
This source targets `@rathnasgala2/schemas@3.8.0` with an exact manifest pin.
|
|
688
|
+
Generation-4 development verifies against the schema sibling/packed candidate.
|
|
689
|
+
The historical `package-lock.json` is not a 3.8.0 registry claim: it must be
|
|
690
|
+
regenerated, together with the SBOM, from the authoritative published 3.8.0
|
|
691
|
+
artifact before release. The 2.8.0->2.11.0 convergence changes none of the four
|
|
692
|
+
roots this renderer validates, for the same reason the 2.7.0-2.8.0 delta below
|
|
693
|
+
did not. Only the `"."` export (`validateGalaDocument`, `GALA_SCHEMA_IDS`) is
|
|
694
|
+
consumed; the 2.6.0 `./runtime-origins` narrow export and every other addition
|
|
695
|
+
through 2.6.1 (new OpenAPI operations, App route/catalog copy, the
|
|
696
|
+
`PrincipalSummary`/`AuthenticatorSummary`/keyset field additions) are
|
|
693
697
|
App/API-surface changes this renderer does not read. The `"."` export's 2.2.2
|
|
694
698
|
browser-safety refactor (Node builtins replaced with browser-safe equivalents
|
|
695
699
|
behind the same public API) is byte-identical in behaviour for a Node consumer
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"attributes":[{"match":"exact-value","name":"data-gala-page-kind","role":"semantic","values":["archive","article","author","error","index","page","profile","series","tag"]},{"match":"exact-value","name":"data-gala-resolved-color-mode","role":"state","values":["dark","light"]},{"match":"exact-value","name":"data-gala-slot","role":"semantic","values":["account-intent","article-end","article-footer-ad","article-preamble","conversation","edition-selector","footer-auxiliary","footer-profile","header-actions","newsletter"]},{"match":"presence","name":"data-gala-publication-root","role":"root","values":[]}],"catalogDigest":"sha256:a10fecf6d43e4392312158f15b66d55a9e2bd3c7816a0747eb2084735d336de5","classSelectors":["g-actions","g-article","g-article-cover","g-article-foot","g-article-grid","g-article-head","g-article-labels","g-article-meta","g-author-bio","g-author-card","g-author-name","g-avatar","g-badge","g-brand","g-brand-name","g-brand-tag","g-brand-text","g-btn","g-byline","g-byline-text","g-card","g-card-body","g-card-excerpt","g-card-foot","g-card-link","g-card-media","g-card-placeholder","g-card-row","g-card-top","g-chip","g-codebar","g-codebar-lang","g-codeblock","g-copy","g-copy-done","g-copy-idle","g-crumbs","g-dek","g-dot","g-eyebrow","g-footer","g-footer-about","g-footer-base","g-footer-brand","g-footer-col","g-footer-grid","g-grid","g-header","g-header-row","g-hero","g-hero-body","g-hero-media","g-icon","g-icon-btn","g-kbd","g-label","g-list","g-main","g-mark","g-menu","g-meta","g-mode-dark","g-mode-icon","g-mode-light","g-mode-system","g-more","g-nav","g-newsletter","g-pager","g-pager-link","g-pager-next","g-pagination","g-panel","g-panel-copy","g-pill","g-pill-count","g-pills","g-progress","g-prose","g-search","g-search-box","g-search-btn","g-search-empty","g-search-hit","g-search-hit-meta","g-search-hit-text","g-search-hit-title","g-search-input","g-search-results","g-section","g-section-head","g-series-box","g-series-card","g-series-here","g-series-list","g-series-n","g-series-tag","g-share","g-skip","g-social","g-sr","g-tag","g-tags","g-toast","g-toc","g-toc-list","g-toc-mobile","g-topic-head","g-topic-hero","g-topic-icon","g-topic-strip","g-wrap","language-bash","language-css","language-diff","language-java","language-javascript","language-json","language-jsx","language-markdown","language-markup","language-python","language-sql","language-tsx","language-typescript","language-yaml","token"],"combinators":[" "," > "," + "," ~ "],"composition":{"compoundOrder":["type","id","class","attribute","pseudo-class","pseudo-element"],"functionalPseudoKeywordArguments":["even","odd"],"functionalSelectorArguments":"compound-only","maximumFunctionalDepth":1,"nthExpressionProfile":"gala-positive-an-plus-b-v2","rootScope":"first-compound-required"},"contractVersion":"3.0.0","functionalPseudos":["is","where","not","nth-child","nth-last-child"],"idSelectors":["gala-appearance-color-mode","main-content"],"orderedLayers":["gala-base","gala-tokens","gala-components","gala-utilities","gala-print"],"profile":"gala-template-styling-contract-v2","pseudoClasses":["active","disabled","focus-visible","hover","visited"],"pseudoElements":["after","before","marker","selection"],"publicThemeSlotHooks":[{"hookId":"code-block","selectorAtom":"pre"},{"hookId":"code-inline","selectorAtom":"code"},{"hookId":"code-language-bash","selectorAtom":".language-bash"},{"hookId":"code-language-css","selectorAtom":".language-css"},{"hookId":"code-language-diff","selectorAtom":".language-diff"},{"hookId":"code-language-java","selectorAtom":".language-java"},{"hookId":"code-language-javascript","selectorAtom":".language-javascript"},{"hookId":"code-language-json","selectorAtom":".language-json"},{"hookId":"code-language-jsx","selectorAtom":".language-jsx"},{"hookId":"code-language-markdown","selectorAtom":".language-markdown"},{"hookId":"code-language-markup","selectorAtom":".language-markup"},{"hookId":"code-language-python","selectorAtom":".language-python"},{"hookId":"code-language-sql","selectorAtom":".language-sql"},{"hookId":"code-language-tsx","selectorAtom":".language-tsx"},{"hookId":"code-language-typescript","selectorAtom":".language-typescript"},{"hookId":"code-language-yaml","selectorAtom":".language-yaml"},{"hookId":"code-token","selectorAtom":".token"},{"hookId":"content-article","selectorAtom":"article"},{"hookId":"control-appearance-toggle","selectorAtom":"#gala-appearance-color-mode"},{"hookId":"control-button","selectorAtom":"button"},{"hookId":"disclosure-details","selectorAtom":"details"},{"hookId":"disclosure-summary","selectorAtom":"summary"},{"hookId":"heading-1","selectorAtom":"h1"},{"hookId":"heading-2","selectorAtom":"h2"},{"hookId":"heading-3","selectorAtom":"h3"},{"hookId":"heading-4","selectorAtom":"h4"},{"hookId":"heading-5","selectorAtom":"h5"},{"hookId":"heading-6","selectorAtom":"h6"},{"hookId":"landmark-footer","selectorAtom":"footer"},{"hookId":"landmark-header","selectorAtom":"header"},{"hookId":"landmark-main","selectorAtom":"main"},{"hookId":"landmark-main-content","selectorAtom":"#main-content"},{"hookId":"landmark-navigation","selectorAtom":"nav"},{"hookId":"landmark-section","selectorAtom":"section"},{"hookId":"media-figure","selectorAtom":"figure"},{"hookId":"media-image","selectorAtom":"img"},{"hookId":"page-archive","selectorAtom":"[data-gala-page-kind=\"archive\"]"},{"hookId":"page-article","selectorAtom":"[data-gala-page-kind=\"article\"]"},{"hookId":"page-author","selectorAtom":"[data-gala-page-kind=\"author\"]"},{"hookId":"page-error","selectorAtom":"[data-gala-page-kind=\"error\"]"},{"hookId":"page-index","selectorAtom":"[data-gala-page-kind=\"index\"]"},{"hookId":"page-page","selectorAtom":"[data-gala-page-kind=\"page\"]"},{"hookId":"page-profile","selectorAtom":"[data-gala-page-kind=\"profile\"]"},{"hookId":"page-series","selectorAtom":"[data-gala-page-kind=\"series\"]"},{"hookId":"page-tag","selectorAtom":"[data-gala-page-kind=\"tag\"]"},{"hookId":"prose-blockquote","selectorAtom":"blockquote"},{"hookId":"prose-divider","selectorAtom":"hr"},{"hookId":"prose-emphasis","selectorAtom":"em"},{"hookId":"prose-link","selectorAtom":"a"},{"hookId":"prose-list-item","selectorAtom":"li"},{"hookId":"prose-list-ordered","selectorAtom":"ol"},{"hookId":"prose-list-unordered","selectorAtom":"ul"},{"hookId":"prose-paragraph","selectorAtom":"p"},{"hookId":"prose-span","selectorAtom":"span"},{"hookId":"prose-strong","selectorAtom":"strong"},{"hookId":"prose-time","selectorAtom":"time"},{"hookId":"slot-account-intent","selectorAtom":"[data-gala-slot=\"account-intent\"]"},{"hookId":"slot-article-end","selectorAtom":"[data-gala-slot=\"article-end\"]"},{"hookId":"slot-article-footer-ad","selectorAtom":"[data-gala-slot=\"article-footer-ad\"]"},{"hookId":"slot-article-preamble","selectorAtom":"[data-gala-slot=\"article-preamble\"]"},{"hookId":"slot-conversation","selectorAtom":"[data-gala-slot=\"conversation\"]"},{"hookId":"slot-edition-selector","selectorAtom":"[data-gala-slot=\"edition-selector\"]"},{"hookId":"slot-footer-auxiliary","selectorAtom":"[data-gala-slot=\"footer-auxiliary\"]"},{"hookId":"slot-footer-profile","selectorAtom":"[data-gala-slot=\"footer-profile\"]"},{"hookId":"slot-header-actions","selectorAtom":"[data-gala-slot=\"header-actions\"]"},{"hookId":"slot-newsletter","selectorAtom":"[data-gala-slot=\"newsletter\"]"},{"hookId":"ui-actions","selectorAtom":".g-actions"},{"hookId":"ui-article","selectorAtom":".g-article"},{"hookId":"ui-article-cover","selectorAtom":".g-article-cover"},{"hookId":"ui-article-foot","selectorAtom":".g-article-foot"},{"hookId":"ui-article-grid","selectorAtom":".g-article-grid"},{"hookId":"ui-article-head","selectorAtom":".g-article-head"},{"hookId":"ui-article-labels","selectorAtom":".g-article-labels"},{"hookId":"ui-article-meta","selectorAtom":".g-article-meta"},{"hookId":"ui-author-bio","selectorAtom":".g-author-bio"},{"hookId":"ui-author-card","selectorAtom":".g-author-card"},{"hookId":"ui-author-name","selectorAtom":".g-author-name"},{"hookId":"ui-avatar","selectorAtom":".g-avatar"},{"hookId":"ui-badge","selectorAtom":".g-badge"},{"hookId":"ui-brand","selectorAtom":".g-brand"},{"hookId":"ui-brand-name","selectorAtom":".g-brand-name"},{"hookId":"ui-brand-tag","selectorAtom":".g-brand-tag"},{"hookId":"ui-brand-text","selectorAtom":".g-brand-text"},{"hookId":"ui-btn","selectorAtom":".g-btn"},{"hookId":"ui-byline","selectorAtom":".g-byline"},{"hookId":"ui-byline-text","selectorAtom":".g-byline-text"},{"hookId":"ui-card","selectorAtom":".g-card"},{"hookId":"ui-card-body","selectorAtom":".g-card-body"},{"hookId":"ui-card-excerpt","selectorAtom":".g-card-excerpt"},{"hookId":"ui-card-foot","selectorAtom":".g-card-foot"},{"hookId":"ui-card-link","selectorAtom":".g-card-link"},{"hookId":"ui-card-media","selectorAtom":".g-card-media"},{"hookId":"ui-card-placeholder","selectorAtom":".g-card-placeholder"},{"hookId":"ui-card-row","selectorAtom":".g-card-row"},{"hookId":"ui-card-top","selectorAtom":".g-card-top"},{"hookId":"ui-chip","selectorAtom":".g-chip"},{"hookId":"ui-codebar","selectorAtom":".g-codebar"},{"hookId":"ui-codebar-lang","selectorAtom":".g-codebar-lang"},{"hookId":"ui-codeblock","selectorAtom":".g-codeblock"},{"hookId":"ui-copy","selectorAtom":".g-copy"},{"hookId":"ui-copy-done","selectorAtom":".g-copy-done"},{"hookId":"ui-copy-idle","selectorAtom":".g-copy-idle"},{"hookId":"ui-crumbs","selectorAtom":".g-crumbs"},{"hookId":"ui-dek","selectorAtom":".g-dek"},{"hookId":"ui-dot","selectorAtom":".g-dot"},{"hookId":"ui-eyebrow","selectorAtom":".g-eyebrow"},{"hookId":"ui-footer","selectorAtom":".g-footer"},{"hookId":"ui-footer-about","selectorAtom":".g-footer-about"},{"hookId":"ui-footer-base","selectorAtom":".g-footer-base"},{"hookId":"ui-footer-brand","selectorAtom":".g-footer-brand"},{"hookId":"ui-footer-col","selectorAtom":".g-footer-col"},{"hookId":"ui-footer-grid","selectorAtom":".g-footer-grid"},{"hookId":"ui-grid","selectorAtom":".g-grid"},{"hookId":"ui-header","selectorAtom":".g-header"},{"hookId":"ui-header-row","selectorAtom":".g-header-row"},{"hookId":"ui-hero","selectorAtom":".g-hero"},{"hookId":"ui-hero-body","selectorAtom":".g-hero-body"},{"hookId":"ui-hero-media","selectorAtom":".g-hero-media"},{"hookId":"ui-icon","selectorAtom":".g-icon"},{"hookId":"ui-icon-btn","selectorAtom":".g-icon-btn"},{"hookId":"ui-kbd","selectorAtom":".g-kbd"},{"hookId":"ui-label","selectorAtom":".g-label"},{"hookId":"ui-list","selectorAtom":".g-list"},{"hookId":"ui-main","selectorAtom":".g-main"},{"hookId":"ui-mark","selectorAtom":".g-mark"},{"hookId":"ui-menu","selectorAtom":".g-menu"},{"hookId":"ui-meta","selectorAtom":".g-meta"},{"hookId":"ui-mode-dark","selectorAtom":".g-mode-dark"},{"hookId":"ui-mode-icon","selectorAtom":".g-mode-icon"},{"hookId":"ui-mode-light","selectorAtom":".g-mode-light"},{"hookId":"ui-mode-system","selectorAtom":".g-mode-system"},{"hookId":"ui-more","selectorAtom":".g-more"},{"hookId":"ui-nav","selectorAtom":".g-nav"},{"hookId":"ui-newsletter","selectorAtom":".g-newsletter"},{"hookId":"ui-pager","selectorAtom":".g-pager"},{"hookId":"ui-pager-link","selectorAtom":".g-pager-link"},{"hookId":"ui-pager-next","selectorAtom":".g-pager-next"},{"hookId":"ui-pagination","selectorAtom":".g-pagination"},{"hookId":"ui-panel","selectorAtom":".g-panel"},{"hookId":"ui-panel-copy","selectorAtom":".g-panel-copy"},{"hookId":"ui-pill","selectorAtom":".g-pill"},{"hookId":"ui-pill-count","selectorAtom":".g-pill-count"},{"hookId":"ui-pills","selectorAtom":".g-pills"},{"hookId":"ui-progress","selectorAtom":".g-progress"},{"hookId":"ui-prose","selectorAtom":".g-prose"},{"hookId":"ui-search","selectorAtom":".g-search"},{"hookId":"ui-search-box","selectorAtom":".g-search-box"},{"hookId":"ui-search-btn","selectorAtom":".g-search-btn"},{"hookId":"ui-search-empty","selectorAtom":".g-search-empty"},{"hookId":"ui-search-hit","selectorAtom":".g-search-hit"},{"hookId":"ui-search-hit-meta","selectorAtom":".g-search-hit-meta"},{"hookId":"ui-search-hit-text","selectorAtom":".g-search-hit-text"},{"hookId":"ui-search-hit-title","selectorAtom":".g-search-hit-title"},{"hookId":"ui-search-input","selectorAtom":".g-search-input"},{"hookId":"ui-search-results","selectorAtom":".g-search-results"},{"hookId":"ui-section","selectorAtom":".g-section"},{"hookId":"ui-section-head","selectorAtom":".g-section-head"},{"hookId":"ui-series-box","selectorAtom":".g-series-box"},{"hookId":"ui-series-card","selectorAtom":".g-series-card"},{"hookId":"ui-series-here","selectorAtom":".g-series-here"},{"hookId":"ui-series-list","selectorAtom":".g-series-list"},{"hookId":"ui-series-n","selectorAtom":".g-series-n"},{"hookId":"ui-series-tag","selectorAtom":".g-series-tag"},{"hookId":"ui-share","selectorAtom":".g-share"},{"hookId":"ui-skip","selectorAtom":".g-skip"},{"hookId":"ui-social","selectorAtom":".g-social"},{"hookId":"ui-sr","selectorAtom":".g-sr"},{"hookId":"ui-tag","selectorAtom":".g-tag"},{"hookId":"ui-tags","selectorAtom":".g-tags"},{"hookId":"ui-toast","selectorAtom":".g-toast"},{"hookId":"ui-toc","selectorAtom":".g-toc"},{"hookId":"ui-toc-list","selectorAtom":".g-toc-list"},{"hookId":"ui-toc-mobile","selectorAtom":".g-toc-mobile"},{"hookId":"ui-topic-head","selectorAtom":".g-topic-head"},{"hookId":"ui-topic-hero","selectorAtom":".g-topic-hero"},{"hookId":"ui-topic-icon","selectorAtom":".g-topic-icon"},{"hookId":"ui-topic-strip","selectorAtom":".g-topic-strip"},{"hookId":"ui-wrap","selectorAtom":".g-wrap"}],"publicationRootSelector":"[data-gala-publication-root]","resolvedPaletteSelectors":{"dark":"[data-gala-publication-root][data-gala-resolved-color-mode=\"dark\"]","light":"[data-gala-publication-root][data-gala-resolved-color-mode=\"light\"]"},"stylesheetLayers":{"components":"gala-components","print":"gala-print","tokens":"gala-tokens","utilities":"gala-utilities"},"templatePackage":"@rathnasgala2/template","templateVersion":"3.0.0","typeSelectors":["a","article","blockquote","button","code","details","em","figure","footer","h1","h2","h3","h4","h5","h6","header","hr","img","li","main","nav","ol","p","pre","section","span","strong","summary","time","ul"]}
|
|
1
|
+
{"attributes":[{"match":"exact-value","name":"data-gala-article-layout","role":"semantic","values":["editorial","full-bleed","issue","prose","technical"]},{"match":"exact-value","name":"data-gala-author-layout","role":"semantic","values":["biography","portfolio","portrait","profile"]},{"match":"exact-value","name":"data-gala-density","role":"semantic","values":["comfortable","compact","spacious"]},{"match":"exact-value","name":"data-gala-footer-layout","role":"semantic","values":["compact","expanded"]},{"match":"exact-value","name":"data-gala-header-layout","role":"semantic","values":["compact","masthead","minimal","publication","utility"]},{"match":"exact-value","name":"data-gala-home-layout","role":"semantic","values":["chronological","gallery","magazine","newspaper","topic-index"]},{"match":"exact-value","name":"data-gala-listing-layout","role":"semantic","values":["dated-rows","image-grid","issues","rows"]},{"match":"exact-value","name":"data-gala-media-ratio","role":"semantic","values":["landscape","mixed"]},{"match":"exact-value","name":"data-gala-page-kind","role":"semantic","values":["archive","article","author","error","index","page","profile","series","tag"]},{"match":"exact-value","name":"data-gala-profile","role":"semantic","values":["developer","editorial","newsletter","personal","visual"]},{"match":"exact-value","name":"data-gala-resolved-color-mode","role":"state","values":["dark","light"]},{"match":"exact-value","name":"data-gala-slot","role":"semantic","values":["account-intent","article-end","article-footer-ad","article-preamble","conversation","edition-selector","footer-auxiliary","footer-profile","header-actions","newsletter"]},{"match":"presence","name":"data-gala-publication-root","role":"root","values":[]}],"catalogDigest":"sha256:63a76754b591a3cda91a4be1f43bdb3fe1d44cf4f9be766154f3944a043399b5","classSelectors":["g-actions","g-article","g-article-cover","g-article-cover-full-bleed","g-article-foot","g-article-grid","g-article-head","g-article-labels","g-article-meta","g-author-bio","g-author-card","g-author-name","g-avatar","g-badge","g-brand","g-brand-name","g-brand-tag","g-brand-text","g-btn","g-byline","g-byline-text","g-card","g-card-body","g-card-excerpt","g-card-foot","g-card-link","g-card-media","g-card-placeholder","g-card-row","g-card-top","g-chip","g-codebar","g-codebar-lang","g-codeblock","g-copy","g-copy-done","g-copy-idle","g-crumbs","g-date-stamp","g-dated-list","g-dated-row","g-dek","g-dot","g-eyebrow","g-footer","g-footer-about","g-footer-base","g-footer-brand","g-footer-col","g-footer-grid","g-grid","g-header","g-header-row","g-hero","g-hero-body","g-hero-media","g-icon","g-icon-btn","g-kbd","g-label","g-list","g-main","g-mark","g-menu","g-meta","g-mode-dark","g-mode-icon","g-mode-light","g-mode-system","g-more","g-nav","g-newsletter","g-pager","g-pager-link","g-pager-next","g-pagination","g-panel","g-panel-copy","g-pill","g-pill-count","g-pills","g-progress","g-prose","g-search","g-search-box","g-search-btn","g-search-empty","g-search-hit","g-search-hit-meta","g-search-hit-text","g-search-hit-title","g-search-input","g-search-results","g-section","g-section-head","g-series-box","g-series-card","g-series-here","g-series-list","g-series-n","g-series-tag","g-share","g-skip","g-social","g-sr","g-tag","g-tags","g-toast","g-toc","g-toc-list","g-toc-mobile","g-topic-head","g-topic-hero","g-topic-icon","g-topic-strip","g-wrap","language-bash","language-css","language-diff","language-java","language-javascript","language-json","language-jsx","language-markdown","language-markup","language-python","language-sql","language-tsx","language-typescript","language-yaml","token"],"combinators":[" "," > "," + "," ~ "],"composition":{"compoundOrder":["type","id","class","attribute","pseudo-class","pseudo-element"],"functionalPseudoKeywordArguments":["even","odd"],"functionalSelectorArguments":"compound-only","maximumFunctionalDepth":1,"nthExpressionProfile":"gala-positive-an-plus-b-v2","rootScope":"first-compound-required"},"contractVersion":"4.0.0","functionalPseudos":["is","where","not","nth-child","nth-last-child"],"idSelectors":["gala-appearance-color-mode","main-content"],"orderedLayers":["gala-base","gala-tokens","gala-components","gala-utilities","gala-print"],"profile":"gala-template-styling-contract-v2","pseudoClasses":["active","disabled","focus-visible","hover","visited"],"pseudoElements":["after","before","marker","selection"],"publicThemeSlotHooks":[{"hookId":"code-block","selectorAtom":"pre"},{"hookId":"code-inline","selectorAtom":"code"},{"hookId":"code-language-bash","selectorAtom":".language-bash"},{"hookId":"code-language-css","selectorAtom":".language-css"},{"hookId":"code-language-diff","selectorAtom":".language-diff"},{"hookId":"code-language-java","selectorAtom":".language-java"},{"hookId":"code-language-javascript","selectorAtom":".language-javascript"},{"hookId":"code-language-json","selectorAtom":".language-json"},{"hookId":"code-language-jsx","selectorAtom":".language-jsx"},{"hookId":"code-language-markdown","selectorAtom":".language-markdown"},{"hookId":"code-language-markup","selectorAtom":".language-markup"},{"hookId":"code-language-python","selectorAtom":".language-python"},{"hookId":"code-language-sql","selectorAtom":".language-sql"},{"hookId":"code-language-tsx","selectorAtom":".language-tsx"},{"hookId":"code-language-typescript","selectorAtom":".language-typescript"},{"hookId":"code-language-yaml","selectorAtom":".language-yaml"},{"hookId":"code-token","selectorAtom":".token"},{"hookId":"composition-article-layout-editorial","selectorAtom":"[data-gala-article-layout=\"editorial\"]"},{"hookId":"composition-article-layout-full-bleed","selectorAtom":"[data-gala-article-layout=\"full-bleed\"]"},{"hookId":"composition-article-layout-issue","selectorAtom":"[data-gala-article-layout=\"issue\"]"},{"hookId":"composition-article-layout-prose","selectorAtom":"[data-gala-article-layout=\"prose\"]"},{"hookId":"composition-article-layout-technical","selectorAtom":"[data-gala-article-layout=\"technical\"]"},{"hookId":"composition-author-layout-biography","selectorAtom":"[data-gala-author-layout=\"biography\"]"},{"hookId":"composition-author-layout-portfolio","selectorAtom":"[data-gala-author-layout=\"portfolio\"]"},{"hookId":"composition-author-layout-portrait","selectorAtom":"[data-gala-author-layout=\"portrait\"]"},{"hookId":"composition-author-layout-profile","selectorAtom":"[data-gala-author-layout=\"profile\"]"},{"hookId":"composition-density-comfortable","selectorAtom":"[data-gala-density=\"comfortable\"]"},{"hookId":"composition-density-compact","selectorAtom":"[data-gala-density=\"compact\"]"},{"hookId":"composition-density-spacious","selectorAtom":"[data-gala-density=\"spacious\"]"},{"hookId":"composition-footer-layout-compact","selectorAtom":"[data-gala-footer-layout=\"compact\"]"},{"hookId":"composition-footer-layout-expanded","selectorAtom":"[data-gala-footer-layout=\"expanded\"]"},{"hookId":"composition-header-layout-compact","selectorAtom":"[data-gala-header-layout=\"compact\"]"},{"hookId":"composition-header-layout-masthead","selectorAtom":"[data-gala-header-layout=\"masthead\"]"},{"hookId":"composition-header-layout-minimal","selectorAtom":"[data-gala-header-layout=\"minimal\"]"},{"hookId":"composition-header-layout-publication","selectorAtom":"[data-gala-header-layout=\"publication\"]"},{"hookId":"composition-header-layout-utility","selectorAtom":"[data-gala-header-layout=\"utility\"]"},{"hookId":"composition-home-layout-chronological","selectorAtom":"[data-gala-home-layout=\"chronological\"]"},{"hookId":"composition-home-layout-gallery","selectorAtom":"[data-gala-home-layout=\"gallery\"]"},{"hookId":"composition-home-layout-magazine","selectorAtom":"[data-gala-home-layout=\"magazine\"]"},{"hookId":"composition-home-layout-newspaper","selectorAtom":"[data-gala-home-layout=\"newspaper\"]"},{"hookId":"composition-home-layout-topic-index","selectorAtom":"[data-gala-home-layout=\"topic-index\"]"},{"hookId":"composition-listing-layout-dated-rows","selectorAtom":"[data-gala-listing-layout=\"dated-rows\"]"},{"hookId":"composition-listing-layout-image-grid","selectorAtom":"[data-gala-listing-layout=\"image-grid\"]"},{"hookId":"composition-listing-layout-issues","selectorAtom":"[data-gala-listing-layout=\"issues\"]"},{"hookId":"composition-listing-layout-rows","selectorAtom":"[data-gala-listing-layout=\"rows\"]"},{"hookId":"composition-media-ratio-landscape","selectorAtom":"[data-gala-media-ratio=\"landscape\"]"},{"hookId":"composition-media-ratio-mixed","selectorAtom":"[data-gala-media-ratio=\"mixed\"]"},{"hookId":"composition-profile-developer","selectorAtom":"[data-gala-profile=\"developer\"]"},{"hookId":"composition-profile-editorial","selectorAtom":"[data-gala-profile=\"editorial\"]"},{"hookId":"composition-profile-newsletter","selectorAtom":"[data-gala-profile=\"newsletter\"]"},{"hookId":"composition-profile-personal","selectorAtom":"[data-gala-profile=\"personal\"]"},{"hookId":"composition-profile-visual","selectorAtom":"[data-gala-profile=\"visual\"]"},{"hookId":"content-article","selectorAtom":"article"},{"hookId":"control-appearance-toggle","selectorAtom":"#gala-appearance-color-mode"},{"hookId":"control-button","selectorAtom":"button"},{"hookId":"disclosure-details","selectorAtom":"details"},{"hookId":"disclosure-summary","selectorAtom":"summary"},{"hookId":"heading-1","selectorAtom":"h1"},{"hookId":"heading-2","selectorAtom":"h2"},{"hookId":"heading-3","selectorAtom":"h3"},{"hookId":"heading-4","selectorAtom":"h4"},{"hookId":"heading-5","selectorAtom":"h5"},{"hookId":"heading-6","selectorAtom":"h6"},{"hookId":"landmark-footer","selectorAtom":"footer"},{"hookId":"landmark-header","selectorAtom":"header"},{"hookId":"landmark-main","selectorAtom":"main"},{"hookId":"landmark-main-content","selectorAtom":"#main-content"},{"hookId":"landmark-navigation","selectorAtom":"nav"},{"hookId":"landmark-section","selectorAtom":"section"},{"hookId":"media-figure","selectorAtom":"figure"},{"hookId":"media-image","selectorAtom":"img"},{"hookId":"page-archive","selectorAtom":"[data-gala-page-kind=\"archive\"]"},{"hookId":"page-article","selectorAtom":"[data-gala-page-kind=\"article\"]"},{"hookId":"page-author","selectorAtom":"[data-gala-page-kind=\"author\"]"},{"hookId":"page-error","selectorAtom":"[data-gala-page-kind=\"error\"]"},{"hookId":"page-index","selectorAtom":"[data-gala-page-kind=\"index\"]"},{"hookId":"page-page","selectorAtom":"[data-gala-page-kind=\"page\"]"},{"hookId":"page-profile","selectorAtom":"[data-gala-page-kind=\"profile\"]"},{"hookId":"page-series","selectorAtom":"[data-gala-page-kind=\"series\"]"},{"hookId":"page-tag","selectorAtom":"[data-gala-page-kind=\"tag\"]"},{"hookId":"prose-blockquote","selectorAtom":"blockquote"},{"hookId":"prose-divider","selectorAtom":"hr"},{"hookId":"prose-emphasis","selectorAtom":"em"},{"hookId":"prose-link","selectorAtom":"a"},{"hookId":"prose-list-item","selectorAtom":"li"},{"hookId":"prose-list-ordered","selectorAtom":"ol"},{"hookId":"prose-list-unordered","selectorAtom":"ul"},{"hookId":"prose-paragraph","selectorAtom":"p"},{"hookId":"prose-span","selectorAtom":"span"},{"hookId":"prose-strong","selectorAtom":"strong"},{"hookId":"prose-time","selectorAtom":"time"},{"hookId":"slot-account-intent","selectorAtom":"[data-gala-slot=\"account-intent\"]"},{"hookId":"slot-article-end","selectorAtom":"[data-gala-slot=\"article-end\"]"},{"hookId":"slot-article-footer-ad","selectorAtom":"[data-gala-slot=\"article-footer-ad\"]"},{"hookId":"slot-article-preamble","selectorAtom":"[data-gala-slot=\"article-preamble\"]"},{"hookId":"slot-conversation","selectorAtom":"[data-gala-slot=\"conversation\"]"},{"hookId":"slot-edition-selector","selectorAtom":"[data-gala-slot=\"edition-selector\"]"},{"hookId":"slot-footer-auxiliary","selectorAtom":"[data-gala-slot=\"footer-auxiliary\"]"},{"hookId":"slot-footer-profile","selectorAtom":"[data-gala-slot=\"footer-profile\"]"},{"hookId":"slot-header-actions","selectorAtom":"[data-gala-slot=\"header-actions\"]"},{"hookId":"slot-newsletter","selectorAtom":"[data-gala-slot=\"newsletter\"]"},{"hookId":"ui-actions","selectorAtom":".g-actions"},{"hookId":"ui-article","selectorAtom":".g-article"},{"hookId":"ui-article-cover","selectorAtom":".g-article-cover"},{"hookId":"ui-article-cover-full-bleed","selectorAtom":".g-article-cover-full-bleed"},{"hookId":"ui-article-foot","selectorAtom":".g-article-foot"},{"hookId":"ui-article-grid","selectorAtom":".g-article-grid"},{"hookId":"ui-article-head","selectorAtom":".g-article-head"},{"hookId":"ui-article-labels","selectorAtom":".g-article-labels"},{"hookId":"ui-article-meta","selectorAtom":".g-article-meta"},{"hookId":"ui-author-bio","selectorAtom":".g-author-bio"},{"hookId":"ui-author-card","selectorAtom":".g-author-card"},{"hookId":"ui-author-name","selectorAtom":".g-author-name"},{"hookId":"ui-avatar","selectorAtom":".g-avatar"},{"hookId":"ui-badge","selectorAtom":".g-badge"},{"hookId":"ui-brand","selectorAtom":".g-brand"},{"hookId":"ui-brand-name","selectorAtom":".g-brand-name"},{"hookId":"ui-brand-tag","selectorAtom":".g-brand-tag"},{"hookId":"ui-brand-text","selectorAtom":".g-brand-text"},{"hookId":"ui-btn","selectorAtom":".g-btn"},{"hookId":"ui-byline","selectorAtom":".g-byline"},{"hookId":"ui-byline-text","selectorAtom":".g-byline-text"},{"hookId":"ui-card","selectorAtom":".g-card"},{"hookId":"ui-card-body","selectorAtom":".g-card-body"},{"hookId":"ui-card-excerpt","selectorAtom":".g-card-excerpt"},{"hookId":"ui-card-foot","selectorAtom":".g-card-foot"},{"hookId":"ui-card-link","selectorAtom":".g-card-link"},{"hookId":"ui-card-media","selectorAtom":".g-card-media"},{"hookId":"ui-card-placeholder","selectorAtom":".g-card-placeholder"},{"hookId":"ui-card-row","selectorAtom":".g-card-row"},{"hookId":"ui-card-top","selectorAtom":".g-card-top"},{"hookId":"ui-chip","selectorAtom":".g-chip"},{"hookId":"ui-codebar","selectorAtom":".g-codebar"},{"hookId":"ui-codebar-lang","selectorAtom":".g-codebar-lang"},{"hookId":"ui-codeblock","selectorAtom":".g-codeblock"},{"hookId":"ui-copy","selectorAtom":".g-copy"},{"hookId":"ui-copy-done","selectorAtom":".g-copy-done"},{"hookId":"ui-copy-idle","selectorAtom":".g-copy-idle"},{"hookId":"ui-crumbs","selectorAtom":".g-crumbs"},{"hookId":"ui-date-stamp","selectorAtom":".g-date-stamp"},{"hookId":"ui-dated-list","selectorAtom":".g-dated-list"},{"hookId":"ui-dated-row","selectorAtom":".g-dated-row"},{"hookId":"ui-dek","selectorAtom":".g-dek"},{"hookId":"ui-dot","selectorAtom":".g-dot"},{"hookId":"ui-eyebrow","selectorAtom":".g-eyebrow"},{"hookId":"ui-footer","selectorAtom":".g-footer"},{"hookId":"ui-footer-about","selectorAtom":".g-footer-about"},{"hookId":"ui-footer-base","selectorAtom":".g-footer-base"},{"hookId":"ui-footer-brand","selectorAtom":".g-footer-brand"},{"hookId":"ui-footer-col","selectorAtom":".g-footer-col"},{"hookId":"ui-footer-grid","selectorAtom":".g-footer-grid"},{"hookId":"ui-grid","selectorAtom":".g-grid"},{"hookId":"ui-header","selectorAtom":".g-header"},{"hookId":"ui-header-row","selectorAtom":".g-header-row"},{"hookId":"ui-hero","selectorAtom":".g-hero"},{"hookId":"ui-hero-body","selectorAtom":".g-hero-body"},{"hookId":"ui-hero-media","selectorAtom":".g-hero-media"},{"hookId":"ui-icon","selectorAtom":".g-icon"},{"hookId":"ui-icon-btn","selectorAtom":".g-icon-btn"},{"hookId":"ui-kbd","selectorAtom":".g-kbd"},{"hookId":"ui-label","selectorAtom":".g-label"},{"hookId":"ui-list","selectorAtom":".g-list"},{"hookId":"ui-main","selectorAtom":".g-main"},{"hookId":"ui-mark","selectorAtom":".g-mark"},{"hookId":"ui-menu","selectorAtom":".g-menu"},{"hookId":"ui-meta","selectorAtom":".g-meta"},{"hookId":"ui-mode-dark","selectorAtom":".g-mode-dark"},{"hookId":"ui-mode-icon","selectorAtom":".g-mode-icon"},{"hookId":"ui-mode-light","selectorAtom":".g-mode-light"},{"hookId":"ui-mode-system","selectorAtom":".g-mode-system"},{"hookId":"ui-more","selectorAtom":".g-more"},{"hookId":"ui-nav","selectorAtom":".g-nav"},{"hookId":"ui-newsletter","selectorAtom":".g-newsletter"},{"hookId":"ui-pager","selectorAtom":".g-pager"},{"hookId":"ui-pager-link","selectorAtom":".g-pager-link"},{"hookId":"ui-pager-next","selectorAtom":".g-pager-next"},{"hookId":"ui-pagination","selectorAtom":".g-pagination"},{"hookId":"ui-panel","selectorAtom":".g-panel"},{"hookId":"ui-panel-copy","selectorAtom":".g-panel-copy"},{"hookId":"ui-pill","selectorAtom":".g-pill"},{"hookId":"ui-pill-count","selectorAtom":".g-pill-count"},{"hookId":"ui-pills","selectorAtom":".g-pills"},{"hookId":"ui-progress","selectorAtom":".g-progress"},{"hookId":"ui-prose","selectorAtom":".g-prose"},{"hookId":"ui-search","selectorAtom":".g-search"},{"hookId":"ui-search-box","selectorAtom":".g-search-box"},{"hookId":"ui-search-btn","selectorAtom":".g-search-btn"},{"hookId":"ui-search-empty","selectorAtom":".g-search-empty"},{"hookId":"ui-search-hit","selectorAtom":".g-search-hit"},{"hookId":"ui-search-hit-meta","selectorAtom":".g-search-hit-meta"},{"hookId":"ui-search-hit-text","selectorAtom":".g-search-hit-text"},{"hookId":"ui-search-hit-title","selectorAtom":".g-search-hit-title"},{"hookId":"ui-search-input","selectorAtom":".g-search-input"},{"hookId":"ui-search-results","selectorAtom":".g-search-results"},{"hookId":"ui-section","selectorAtom":".g-section"},{"hookId":"ui-section-head","selectorAtom":".g-section-head"},{"hookId":"ui-series-box","selectorAtom":".g-series-box"},{"hookId":"ui-series-card","selectorAtom":".g-series-card"},{"hookId":"ui-series-here","selectorAtom":".g-series-here"},{"hookId":"ui-series-list","selectorAtom":".g-series-list"},{"hookId":"ui-series-n","selectorAtom":".g-series-n"},{"hookId":"ui-series-tag","selectorAtom":".g-series-tag"},{"hookId":"ui-share","selectorAtom":".g-share"},{"hookId":"ui-skip","selectorAtom":".g-skip"},{"hookId":"ui-social","selectorAtom":".g-social"},{"hookId":"ui-sr","selectorAtom":".g-sr"},{"hookId":"ui-tag","selectorAtom":".g-tag"},{"hookId":"ui-tags","selectorAtom":".g-tags"},{"hookId":"ui-toast","selectorAtom":".g-toast"},{"hookId":"ui-toc","selectorAtom":".g-toc"},{"hookId":"ui-toc-list","selectorAtom":".g-toc-list"},{"hookId":"ui-toc-mobile","selectorAtom":".g-toc-mobile"},{"hookId":"ui-topic-head","selectorAtom":".g-topic-head"},{"hookId":"ui-topic-hero","selectorAtom":".g-topic-hero"},{"hookId":"ui-topic-icon","selectorAtom":".g-topic-icon"},{"hookId":"ui-topic-strip","selectorAtom":".g-topic-strip"},{"hookId":"ui-wrap","selectorAtom":".g-wrap"}],"publicationRootSelector":"[data-gala-publication-root]","resolvedPaletteSelectors":{"dark":"[data-gala-publication-root][data-gala-resolved-color-mode=\"dark\"]","light":"[data-gala-publication-root][data-gala-resolved-color-mode=\"light\"]"},"stylesheetLayers":{"components":"gala-components","print":"gala-print","tokens":"gala-tokens","utilities":"gala-utilities"},"templatePackage":"@rathnasgala2/template","templateVersion":"4.0.0","typeSelectors":["a","article","blockquote","button","code","details","em","figure","footer","h1","h2","h3","h4","h5","h6","header","hr","img","li","main","nav","ol","p","pre","section","span","strong","summary","time","ul"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@rathnasgala2/template",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "4.0.0",
|
|
4
4
|
"description": "Deterministic Eleventy-backed static publication renderer for Galascribe portable repositories.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "Apache-2.0",
|
|
@@ -72,11 +72,13 @@
|
|
|
72
72
|
"dependencies": {
|
|
73
73
|
"@11ty/eleventy": "3.1.6",
|
|
74
74
|
"@11ty/eleventy-plugin-syntaxhighlight": "5.0.2",
|
|
75
|
-
"@rathnasgala2/schemas": "3.3.0",
|
|
76
75
|
"jpeg-js": "0.4.4",
|
|
77
76
|
"markdown-it": "14.3.1",
|
|
78
77
|
"sanitize-html": "2.17.7"
|
|
79
78
|
},
|
|
79
|
+
"peerDependencies": {
|
|
80
|
+
"@rathnasgala2/schemas": "3.8.0"
|
|
81
|
+
},
|
|
80
82
|
"devDependencies": {
|
|
81
83
|
"@cyclonedx/cyclonedx-npm": "6.0.1",
|
|
82
84
|
"@eslint/js": "10.0.1",
|
package/src/core/index.js
CHANGED
|
@@ -139,6 +139,7 @@ import {
|
|
|
139
139
|
defaultThemeStylesheetLinksHtml,
|
|
140
140
|
loadThemeAssets,
|
|
141
141
|
} from './internal/theme-assets.js';
|
|
142
|
+
import { EDITORIAL_COMPOSITION } from './internal/template-composition.js';
|
|
142
143
|
import { resolveTextDirection } from './internal/text-direction.js';
|
|
143
144
|
import {
|
|
144
145
|
escapeHtml,
|
|
@@ -189,7 +190,7 @@ export const TEMPLATE_PACKAGE_NAME = '@rathnasgala2/template';
|
|
|
189
190
|
*
|
|
190
191
|
* @type {string}
|
|
191
192
|
*/
|
|
192
|
-
export const TEMPLATE_PACKAGE_VERSION = '
|
|
193
|
+
export const TEMPLATE_PACKAGE_VERSION = '4.0.0';
|
|
193
194
|
|
|
194
195
|
/**
|
|
195
196
|
* Validate the caller-supplied render options, independent of build-input
|
|
@@ -391,6 +392,22 @@ export async function renderPublication(buildInput, options) {
|
|
|
391
392
|
const urlPrefix = derivePublicBasePath(validatedInput.baseUrl, '/');
|
|
392
393
|
const homeRoute = joinPublicRoute(publicBasePath, '/');
|
|
393
394
|
|
|
395
|
+
// Admit the selected generation-4 theme and its complete structural
|
|
396
|
+
// composition before any output directory is created. Theme-less calls
|
|
397
|
+
// use the renderer's Editorial composition and the conventional print
|
|
398
|
+
// stylesheet link; a supplied theme never receives that fallback.
|
|
399
|
+
const themeAssetsResult = options.themeDirectory
|
|
400
|
+
? await loadThemeAssets({
|
|
401
|
+
themeDirectory: path.resolve(options.themeDirectory),
|
|
402
|
+
basePath: validatedInput.basePath,
|
|
403
|
+
publicBasePath,
|
|
404
|
+
})
|
|
405
|
+
: undefined;
|
|
406
|
+
const themeStylesheetLinksHtml = themeAssetsResult
|
|
407
|
+
? themeAssetsResult.linkTagsHtml
|
|
408
|
+
: defaultThemeStylesheetLinksHtml(publicBasePath);
|
|
409
|
+
const composition = themeAssetsResult?.composition ?? EDITORIAL_COMPOSITION;
|
|
410
|
+
|
|
394
411
|
const appearanceControlHtml = renderAppearanceControl({
|
|
395
412
|
messages: siteMessages,
|
|
396
413
|
});
|
|
@@ -495,6 +512,8 @@ export async function renderPublication(buildInput, options) {
|
|
|
495
512
|
showAttribution:
|
|
496
513
|
validatedInput.appearance.attribution?.showMadeWith !== false,
|
|
497
514
|
messages: siteMessages,
|
|
515
|
+
profile: composition.profile,
|
|
516
|
+
footerLayout: composition.footerLayout,
|
|
498
517
|
});
|
|
499
518
|
|
|
500
519
|
/**
|
|
@@ -522,6 +541,8 @@ export async function renderPublication(buildInput, options) {
|
|
|
522
541
|
searchIndexHref,
|
|
523
542
|
appearanceControlHtml,
|
|
524
543
|
messages: siteMessages,
|
|
544
|
+
profile: composition.profile,
|
|
545
|
+
headerLayout: composition.headerLayout,
|
|
525
546
|
});
|
|
526
547
|
|
|
527
548
|
// The site-wide feeds, resolved once so every page's feed-discovery
|
|
@@ -540,22 +561,6 @@ export async function renderPublication(buildInput, options) {
|
|
|
540
561
|
`/${GALA_BASE_STYLESHEET_PATH}`,
|
|
541
562
|
);
|
|
542
563
|
|
|
543
|
-
// The selected theme package's copied stylesheets/passive assets and the
|
|
544
|
-
// ordered `<link>` markup every generated page's `<head>` inserts.
|
|
545
|
-
// Run before page assembly (same reasoning as the media pipeline above):
|
|
546
|
-
// every page's `data.themeStylesheetLinksHtml` needs the same one
|
|
547
|
-
// already-rendered fragment.
|
|
548
|
-
const themeAssetsResult = options.themeDirectory
|
|
549
|
-
? await loadThemeAssets({
|
|
550
|
-
themeDirectory: path.resolve(options.themeDirectory),
|
|
551
|
-
basePath: validatedInput.basePath,
|
|
552
|
-
publicBasePath,
|
|
553
|
-
})
|
|
554
|
-
: undefined;
|
|
555
|
-
const themeStylesheetLinksHtml = themeAssetsResult
|
|
556
|
-
? themeAssetsResult.linkTagsHtml
|
|
557
|
-
: defaultThemeStylesheetLinksHtml(publicBasePath);
|
|
558
|
-
|
|
559
564
|
/** @type {{virtualPath: string, content: string, permalink: string, layout?: string, data?: Record<string, unknown>}[]} */
|
|
560
565
|
const contentPages = [];
|
|
561
566
|
/** @type {{joinedSource: string, joinedTarget: string, publicTarget: string, filePath: string}[]} */
|
|
@@ -567,6 +572,7 @@ export async function renderPublication(buildInput, options) {
|
|
|
567
572
|
mediaAssets,
|
|
568
573
|
mediaDimensions,
|
|
569
574
|
interactions: interactionsOn ? interactionsModule : undefined,
|
|
575
|
+
composition,
|
|
570
576
|
});
|
|
571
577
|
/** @type {Set<string>} output paths of the interaction-bearing routes */
|
|
572
578
|
const interactionBearingPaths = new Set();
|
|
@@ -629,6 +635,7 @@ export async function renderPublication(buildInput, options) {
|
|
|
629
635
|
cspMetaTag,
|
|
630
636
|
baseStylesheetHref: baseStylesheetHrefValue,
|
|
631
637
|
themeStylesheetLinksHtml,
|
|
638
|
+
composition,
|
|
632
639
|
},
|
|
633
640
|
});
|
|
634
641
|
});
|
|
@@ -701,6 +708,7 @@ export async function renderPublication(buildInput, options) {
|
|
|
701
708
|
cspMetaTag,
|
|
702
709
|
baseStylesheetHref: baseStylesheetHrefValue,
|
|
703
710
|
themeStylesheetLinksHtml,
|
|
711
|
+
composition,
|
|
704
712
|
},
|
|
705
713
|
});
|
|
706
714
|
|
|
@@ -259,7 +259,7 @@ export const GALA_BASE_COMPONENT_CSS = `
|
|
|
259
259
|
outline-offset: 3px;
|
|
260
260
|
}
|
|
261
261
|
[data-gala-publication-root] img { display: block; max-width: 100%; height: auto; }
|
|
262
|
-
[data-gala-publication-root] a { color: inherit; text-decoration: none; }
|
|
262
|
+
[data-gala-publication-root] :where(a) { color: inherit; text-decoration: none; }
|
|
263
263
|
[data-gala-publication-root] h1, [data-gala-publication-root] h2, [data-gala-publication-root] h3, [data-gala-publication-root] p { margin: 0; }
|
|
264
264
|
[data-gala-publication-root] button { font: inherit; color: inherit; }
|
|
265
265
|
[data-gala-publication-root] ul, [data-gala-publication-root] ol { margin: 0; padding: 0; list-style: none; }
|
|
@@ -483,6 +483,12 @@ export const GALA_BASE_COMPONENT_CSS = `
|
|
|
483
483
|
.g-card-row .g-card-media, .g-card-row .g-card-placeholder { aspect-ratio: 16 / 9; height: 100%; border-bottom: 0; border-right: var(--gala-border-media-divider); }
|
|
484
484
|
.g-card-row .g-card-body { padding: clamp(1rem, 2.5vw, 1.75rem); }
|
|
485
485
|
.g-card-row h2, .g-card-row h3 { font-size: clamp(1.3rem, 1rem + 1vw, 1.75rem); }
|
|
486
|
+
.g-dated-list { gap: 0; }
|
|
487
|
+
.g-dated-row { display: grid; grid-template-columns: minmax(8rem, 1fr) minmax(0, 5fr); gap: clamp(1rem, 3vw, 2rem); align-items: start; padding-block: var(--gala-space-4); border-top: var(--gala-border-row-divider); }
|
|
488
|
+
.g-date-stamp { padding-top: var(--gala-space-3); color: var(--gala-color-text-muted); font-family: var(--gala-font-ui); font-size: .8125rem; font-variant-numeric: tabular-nums; }
|
|
489
|
+
.g-dated-row .g-card-row { grid-template-columns: minmax(0, 1fr); padding: 0; border-bottom: 0; box-shadow: none; }
|
|
490
|
+
.g-dated-row .g-card-row .g-card-media, .g-dated-row .g-card-row .g-card-placeholder { display: none; }
|
|
491
|
+
.g-dated-row .g-card-foot .g-meta > time:first-child, .g-dated-row .g-card-foot .g-meta > time:first-child + .g-dot { display: none; }
|
|
486
492
|
|
|
487
493
|
/* ---------- series ---------- */
|
|
488
494
|
.g-series-card {
|
|
@@ -527,6 +533,12 @@ export const GALA_BASE_COMPONENT_CSS = `
|
|
|
527
533
|
[data-gala-slot="edition-selector"] { display: grid; grid-template-columns: minmax(0, 1fr); gap: var(--gala-space-2); min-width: 0; max-width: 100%; }
|
|
528
534
|
.g-article-cover { margin-block: 0; }
|
|
529
535
|
.g-article-cover img { width: 100%; height: auto; aspect-ratio: 21 / 9; object-fit: cover; border-radius: var(--gala-radius-large); border: var(--gala-border-card); box-shadow: var(--gala-shadow-card); filter: var(--gala-media-filter); }
|
|
536
|
+
.g-article-cover-full-bleed { width: 100%; max-width: none; margin: 0; padding-inline: 0; }
|
|
537
|
+
.g-article-cover-full-bleed img { aspect-ratio: 16 / 9; border-inline: 0; border-radius: 0; }
|
|
538
|
+
[data-gala-media-ratio="mixed"] .g-hero-media { aspect-ratio: 3 / 2; }
|
|
539
|
+
[data-gala-media-ratio="mixed"] .g-grid > .g-card:nth-child(3n + 1) :is(.g-card-media, .g-card-placeholder) { aspect-ratio: 4 / 5; }
|
|
540
|
+
[data-gala-media-ratio="mixed"] .g-grid > .g-card:nth-child(3n + 2) :is(.g-card-media, .g-card-placeholder) { aspect-ratio: 3 / 2; }
|
|
541
|
+
[data-gala-media-ratio="mixed"] .g-grid > .g-card:nth-child(3n) :is(.g-card-media, .g-card-placeholder) { aspect-ratio: 1; }
|
|
530
542
|
.g-article-grid { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, var(--gala-content-measure)) minmax(0, 1fr); gap: clamp(1.5rem, 4vw, 3.5rem); padding-block: clamp(2rem, 5vw, 3.5rem) var(--gala-space-4); }
|
|
531
543
|
.g-article-grid > .g-prose { grid-column: 2; }
|
|
532
544
|
.g-toc { position: sticky; top: 6rem; align-self: start; justify-self: end; width: min(100%, 15rem); display: grid; gap: var(--gala-space-3); }
|
|
@@ -810,6 +822,8 @@ export const GALA_BASE_COMPONENT_CSS = `
|
|
|
810
822
|
.g-grid { grid-template-columns: minmax(0, 1fr); }
|
|
811
823
|
.g-card-row { grid-template-columns: minmax(0, 1fr); }
|
|
812
824
|
.g-card-row .g-card-media, .g-card-row .g-card-placeholder { border-right: 0; border-bottom: var(--gala-border-media-divider); height: auto; }
|
|
825
|
+
.g-dated-row { grid-template-columns: minmax(0, 1fr); gap: var(--gala-space-2); }
|
|
826
|
+
.g-date-stamp { padding-top: 0; }
|
|
813
827
|
.g-pager { grid-template-columns: minmax(0, 1fr); }
|
|
814
828
|
.g-pager-next { grid-column: 1; }
|
|
815
829
|
.g-article-cover img { aspect-ratio: 16 / 10; }
|
|
@@ -832,7 +846,7 @@ export const GALA_BASE_COMPONENT_CSS = `
|
|
|
832
846
|
@keyframes g-read { from { transform: scaleX(0); } to { transform: scaleX(1); } }
|
|
833
847
|
}
|
|
834
848
|
@supports (animation-timeline: view()) {
|
|
835
|
-
.g-grid > .g-card, .g-list > .g-card, .g-panel, .g-series-card, .g-author-card, .g-series-box, .g-prose > pre, .g-codeblock, .g-prose > figure, .g-prose > blockquote {
|
|
849
|
+
.g-grid > .g-card, .g-list > .g-card, .g-dated-row, .g-panel, .g-series-card, .g-author-card, .g-series-box, .g-prose > pre, .g-codeblock, .g-prose > figure, .g-prose > blockquote {
|
|
836
850
|
animation: g-reveal linear both; animation-timeline: view(); animation-range: entry 0% entry 55%;
|
|
837
851
|
}
|
|
838
852
|
@keyframes g-reveal { from { opacity: .15; transform: translateY(28px) scale(.985); } }
|
|
@@ -74,15 +74,19 @@ import {
|
|
|
74
74
|
APPEARANCE_TOGGLE_ID,
|
|
75
75
|
} from './contract.js';
|
|
76
76
|
import { PAGE_KIND_ATTRIBUTE, PAGE_KIND_VALUES } from '../page-kinds.js';
|
|
77
|
+
import {
|
|
78
|
+
COMPOSITION_ATTRIBUTES,
|
|
79
|
+
COMPOSITION_ATTRIBUTE_CATALOG,
|
|
80
|
+
} from '../template-composition.js';
|
|
77
81
|
import { SLOT_NAMES } from '../skeleton.js';
|
|
78
82
|
import { canonicalizeJcs, domainDigest } from '../canonical-jcs.js';
|
|
79
83
|
|
|
80
84
|
/** @type {string} */
|
|
81
85
|
export const TEMPLATE_STYLING_CONTRACT_PACKAGE = '@rathnasgala2/template';
|
|
82
86
|
/** @type {string} */
|
|
83
|
-
export const TEMPLATE_STYLING_CONTRACT_VERSION = '
|
|
87
|
+
export const TEMPLATE_STYLING_CONTRACT_VERSION = '4.0.0';
|
|
84
88
|
/** @type {string} */
|
|
85
|
-
export const TEMPLATE_STYLING_CONTRACT_TEMPLATE_VERSION = '
|
|
89
|
+
export const TEMPLATE_STYLING_CONTRACT_TEMPLATE_VERSION = '4.0.0';
|
|
86
90
|
|
|
87
91
|
/** @type {string} the `main-content` landmark's fixed `id`. */
|
|
88
92
|
const MAIN_CONTENT_ID = 'main-content';
|
|
@@ -278,6 +282,9 @@ export const COMPONENT_CLASS_GROUPS = Object.freeze({
|
|
|
278
282
|
'g-section-head',
|
|
279
283
|
'g-grid',
|
|
280
284
|
'g-list',
|
|
285
|
+
'g-dated-list',
|
|
286
|
+
'g-dated-row',
|
|
287
|
+
'g-date-stamp',
|
|
281
288
|
'g-pills',
|
|
282
289
|
'g-pill',
|
|
283
290
|
'g-pill-count',
|
|
@@ -343,6 +350,7 @@ export const COMPONENT_CLASS_GROUPS = Object.freeze({
|
|
|
343
350
|
'g-article-meta',
|
|
344
351
|
'g-share',
|
|
345
352
|
'g-article-cover',
|
|
353
|
+
'g-article-cover-full-bleed',
|
|
346
354
|
'g-article-grid',
|
|
347
355
|
'g-toc',
|
|
348
356
|
'g-toc-list',
|
|
@@ -468,6 +476,13 @@ const ATTRIBUTE_VALUE_HOOKS = Object.freeze([
|
|
|
468
476
|
kind: /** @type {const} */ ('attribute'),
|
|
469
477
|
}),
|
|
470
478
|
),
|
|
479
|
+
...COMPOSITION_ATTRIBUTES.map(({ field, name, value }) =>
|
|
480
|
+
Object.freeze({
|
|
481
|
+
hookId: `composition-${field.replace(/[A-Z]/g, (letter) => `-${letter.toLowerCase()}`)}-${value}`,
|
|
482
|
+
selectorAtom: `[${name}="${value}"]`,
|
|
483
|
+
kind: /** @type {const} */ ('attribute'),
|
|
484
|
+
}),
|
|
485
|
+
),
|
|
471
486
|
]);
|
|
472
487
|
|
|
473
488
|
/** @type {readonly StyleHookDefinition[]} every public hook, unsorted. */
|
|
@@ -524,6 +539,12 @@ export function buildTemplateStylingContract() {
|
|
|
524
539
|
values: sortedUniqueBytes(PAGE_KIND_VALUES),
|
|
525
540
|
role: 'semantic',
|
|
526
541
|
},
|
|
542
|
+
...COMPOSITION_ATTRIBUTE_CATALOG.map(({ name, values }) => ({
|
|
543
|
+
name,
|
|
544
|
+
match: 'exact-value',
|
|
545
|
+
values: sortedUniqueBytes(values),
|
|
546
|
+
role: 'semantic',
|
|
547
|
+
})),
|
|
527
548
|
].sort((a, b) => {
|
|
528
549
|
const bufferA = Buffer.from(canonicalizeJcs(a), 'utf8');
|
|
529
550
|
const bufferB = Buffer.from(canonicalizeJcs(b), 'utf8');
|
|
@@ -648,7 +669,7 @@ export function assertTemplateStylingContractShape(contract) {
|
|
|
648
669
|
if (contract.profile !== 'gala-template-styling-contract-v2') {
|
|
649
670
|
fail('profile');
|
|
650
671
|
}
|
|
651
|
-
if (contract.contractVersion !== '
|
|
672
|
+
if (contract.contractVersion !== '4.0.0') fail('contractVersion');
|
|
652
673
|
if (contract.templatePackage !== '@rathnasgala2/template') {
|
|
653
674
|
fail('templatePackage');
|
|
654
675
|
}
|
|
@@ -52,6 +52,8 @@ function renderMark(name, mark) {
|
|
|
52
52
|
* @param {string} [options.appearanceControlHtml] the already-rendered
|
|
53
53
|
* appearance control, inserted into the `header-actions` slot
|
|
54
54
|
* @param {Readonly<Record<string, string | ((...args: string[]) => string)>>} options.messages
|
|
55
|
+
* @param {string} options.profile the admitted composition profile
|
|
56
|
+
* @param {string} options.headerLayout the admitted composition's header layout
|
|
55
57
|
* @returns {string} the rendered header
|
|
56
58
|
*/
|
|
57
59
|
export function renderHeader({
|
|
@@ -66,6 +68,8 @@ export function renderHeader({
|
|
|
66
68
|
searchIndexHref,
|
|
67
69
|
appearanceControlHtml,
|
|
68
70
|
messages,
|
|
71
|
+
profile,
|
|
72
|
+
headerLayout,
|
|
69
73
|
}) {
|
|
70
74
|
const label = (/** @type {string} */ key) =>
|
|
71
75
|
escapeHtml(/** @type {string} */ (messages[key]));
|
|
@@ -74,19 +78,28 @@ export function renderHeader({
|
|
|
74
78
|
? `<details class="g-menu"><summary>${icon('menu')}<span class="g-sr">${label('menuSummaryLabel')}</span></summary>` +
|
|
75
79
|
`<ul>${navItems.map((item) => renderNavItem(item, currentRoute, urlPrefix)).join('')}</ul></details>`
|
|
76
80
|
: '';
|
|
77
|
-
|
|
78
|
-
`<header class="g-header"><div class="g-wrap g-header-row">` +
|
|
81
|
+
const brand =
|
|
79
82
|
`<a class="g-brand" href="${escapeHtml(homeRoute)}">${renderMark(publicationName, brandMark)}` +
|
|
80
83
|
`<span class="g-brand-text"><span class="g-brand-name">${escapeHtml(publicationName)}</span>` +
|
|
81
|
-
`<span class="g-brand-tag">${escapeHtml(tagline)}</span></span></a
|
|
82
|
-
|
|
84
|
+
`<span class="g-brand-tag">${escapeHtml(tagline)}</span></span></a>`;
|
|
85
|
+
const actions =
|
|
83
86
|
`<div class="g-actions">` +
|
|
84
87
|
`<button class="g-search-btn" type="button" hidden data-action="search" data-search-index="${escapeHtml(searchIndexHref)}" aria-label="${label('searchButtonAriaLabel')}">` +
|
|
85
88
|
`${icon('search')}<span>${label('searchButtonLabel')}</span></button>` +
|
|
86
89
|
renderSlot('header-actions', { html: appearanceControlHtml }) +
|
|
87
90
|
menu +
|
|
88
|
-
`</div
|
|
89
|
-
|
|
91
|
+
`</div>`;
|
|
92
|
+
const content =
|
|
93
|
+
profile === 'newsletter'
|
|
94
|
+
? actions + brand + navHtml
|
|
95
|
+
: profile === 'visual'
|
|
96
|
+
? brand + actions + navHtml
|
|
97
|
+
: profile === 'personal'
|
|
98
|
+
? navHtml + brand + actions
|
|
99
|
+
: profile === 'developer'
|
|
100
|
+
? navHtml + actions + brand
|
|
101
|
+
: brand + navHtml + actions;
|
|
102
|
+
return `<header class="g-header" data-gala-header-layout="${escapeHtml(headerLayout)}"><div class="g-wrap g-header-row">${content}</div></header>`;
|
|
90
103
|
}
|
|
91
104
|
|
|
92
105
|
/**
|
|
@@ -146,6 +159,8 @@ function renderSocialLinks(socialLinks, rssHref, messages) {
|
|
|
146
159
|
* attribution line renders: the build input's
|
|
147
160
|
* `appearance.attribution.showMadeWith`, shown when absent
|
|
148
161
|
* @param {Readonly<Record<string, string | ((...args: string[]) => string)>>} options.messages
|
|
162
|
+
* @param {string} options.profile the admitted composition profile
|
|
163
|
+
* @param {string} options.footerLayout the admitted composition's footer layout
|
|
149
164
|
* @returns {string} the rendered footer
|
|
150
165
|
*/
|
|
151
166
|
export function renderFooter({
|
|
@@ -163,6 +178,8 @@ export function renderFooter({
|
|
|
163
178
|
copyrightText,
|
|
164
179
|
showAttribution,
|
|
165
180
|
messages,
|
|
181
|
+
profile,
|
|
182
|
+
footerLayout,
|
|
166
183
|
}) {
|
|
167
184
|
const label = (/** @type {string} */ key) =>
|
|
168
185
|
escapeHtml(/** @type {string} */ (messages[key]));
|
|
@@ -176,20 +193,31 @@ export function renderFooter({
|
|
|
176
193
|
? ''
|
|
177
194
|
: `<nav class="g-footer-col" aria-label="${label(labelKey)}"><p class="g-label">${label(labelKey)}</p>` +
|
|
178
195
|
`<ul>${items.map((item) => renderNavItem(item, undefined, urlPrefix)).join('')}</ul></nav>`;
|
|
179
|
-
|
|
180
|
-
`<footer class="g-footer"><div class="g-wrap g-footer-grid">` +
|
|
196
|
+
const brand =
|
|
181
197
|
`<div class="g-footer-brand">` +
|
|
182
198
|
`<a class="g-brand" href="${escapeHtml(homeRoute)}">${renderMark(publicationName, brandMark)}` +
|
|
183
199
|
`<span class="g-brand-name">${escapeHtml(publicationName)}</span></a>` +
|
|
184
200
|
`<p class="g-footer-about">${escapeHtml(description)}</p>` +
|
|
185
201
|
renderSocialLinks(socialLinks, rssHref, messages) +
|
|
186
|
-
`</div
|
|
187
|
-
|
|
188
|
-
|
|
202
|
+
`</div>`;
|
|
203
|
+
const primary = column('exploreColumnLabel', primaryItems);
|
|
204
|
+
const secondary = column('footerNavigationLabel', footerItems);
|
|
205
|
+
const profileCard =
|
|
189
206
|
`<div class="g-footer-col">` +
|
|
190
207
|
renderSlot('footer-profile', { html: authorHtml + footerProfileHtml }) +
|
|
191
|
-
`</div
|
|
192
|
-
|
|
208
|
+
`</div>`;
|
|
209
|
+
const grid =
|
|
210
|
+
profile === 'newsletter'
|
|
211
|
+
? brand + profileCard + primary + secondary
|
|
212
|
+
: profile === 'visual'
|
|
213
|
+
? brand + primary + profileCard + secondary
|
|
214
|
+
: profile === 'personal'
|
|
215
|
+
? profileCard + brand + primary + secondary
|
|
216
|
+
: profile === 'developer'
|
|
217
|
+
? primary + secondary + brand + profileCard
|
|
218
|
+
: brand + primary + secondary + profileCard;
|
|
219
|
+
return (
|
|
220
|
+
`<footer class="g-footer" data-gala-footer-layout="${escapeHtml(footerLayout)}"><div class="g-wrap g-footer-grid">${grid}</div>` +
|
|
193
221
|
renderSlot('footer-auxiliary') +
|
|
194
222
|
renderSlot('account-intent') +
|
|
195
223
|
renderSlot('conversation') +
|
|
@@ -172,7 +172,7 @@ const SKELETON_LAYOUT_SOURCE = [
|
|
|
172
172
|
'<link rel="stylesheet" href="{{ baseStylesheetHref }}">',
|
|
173
173
|
'{{ themeStylesheetLinksHtml | safe }}',
|
|
174
174
|
'</head>',
|
|
175
|
-
`<body ${PAGE_KIND_ATTRIBUTE}="{{ pageKind }}">`,
|
|
175
|
+
`<body ${PAGE_KIND_ATTRIBUTE}="{{ pageKind }}" data-gala-profile="{{ composition.profile }}" data-gala-home-layout="{{ composition.homeLayout }}" data-gala-article-layout="{{ composition.articleLayout }}" data-gala-author-layout="{{ composition.authorLayout }}" data-gala-listing-layout="{{ composition.listingLayout }}" data-gala-header-layout="{{ composition.headerLayout }}" data-gala-footer-layout="{{ composition.footerLayout }}" data-gala-media-ratio="{{ composition.mediaRatio }}" data-gala-density="{{ composition.density }}">`,
|
|
176
176
|
'{{ content | safe }}',
|
|
177
177
|
'</body>',
|
|
178
178
|
'</html>',
|
|
@@ -88,6 +88,10 @@ import { getMessages } from './messages.js';
|
|
|
88
88
|
import { resolveTextDirection } from './text-direction.js';
|
|
89
89
|
import { deriveAuthorSlugs, routeSegmentForLabel } from './route-labels.js';
|
|
90
90
|
import { derivePublicBasePath, joinPublicRoute } from './route.js';
|
|
91
|
+
import {
|
|
92
|
+
assertSupportedComposition,
|
|
93
|
+
EDITORIAL_COMPOSITION,
|
|
94
|
+
} from './template-composition.js';
|
|
91
95
|
|
|
92
96
|
/** Listing page size (index and per-year archive pages). Scoped decision:
|
|
93
97
|
* this renderer has no externally fixed page size; 10 is a deterministic,
|
|
@@ -383,11 +387,46 @@ export function homeDocumentTitle(name, tagline) {
|
|
|
383
387
|
* @param {import('../../../types/index.d.ts').InteractionsModule} [options.interactions]
|
|
384
388
|
* the validated interactions module; when set, every article page carries
|
|
385
389
|
* the interactions section and is interaction-bearing
|
|
390
|
+
* @param {unknown} [options.composition] the schema-validated structural
|
|
391
|
+
* composition selected by the theme; defaults to Editorial only for
|
|
392
|
+
* theme-less renderer use
|
|
386
393
|
* @returns {GeneratedPage[]} every generated page, in a stable, deterministic
|
|
387
394
|
* order
|
|
388
395
|
*/
|
|
389
396
|
export function buildGeneratedPages(validatedInput, options) {
|
|
390
397
|
const { publication, authors, content, basePath, baseUrl } = validatedInput;
|
|
398
|
+
const composition = assertSupportedComposition(
|
|
399
|
+
options.composition ?? EDITORIAL_COMPOSITION,
|
|
400
|
+
);
|
|
401
|
+
/**
|
|
402
|
+
* Preserve every content region while giving each article direction its
|
|
403
|
+
* own reading sequence and semantic container.
|
|
404
|
+
*
|
|
405
|
+
* @param {{head: string, cover: string, toc: string, prose: string, foot: string}} parts
|
|
406
|
+
* @returns {string}
|
|
407
|
+
*/
|
|
408
|
+
const articleStructure = ({ head, cover, toc, prose, foot }) => {
|
|
409
|
+
/**
|
|
410
|
+
* @param {string} contents rendered article regions
|
|
411
|
+
* @param {string} [element] semantic wrapper element
|
|
412
|
+
* @returns {string}
|
|
413
|
+
*/
|
|
414
|
+
const grid = (contents, element = 'div') =>
|
|
415
|
+
`<${element} class="g-wrap g-article-grid">${contents}</${element}>`;
|
|
416
|
+
if (composition.profile === 'newsletter') {
|
|
417
|
+
return `<section>${head}${cover}${grid(prose + toc, 'section')}${foot}</section>`;
|
|
418
|
+
}
|
|
419
|
+
if (composition.profile === 'visual') {
|
|
420
|
+
return `<div>${cover}${head}${grid(prose + toc)}</div>${foot}`;
|
|
421
|
+
}
|
|
422
|
+
if (composition.profile === 'personal') {
|
|
423
|
+
return `<section>${head}${cover}${grid(prose)}${toc ? grid(toc, 'section') : ''}${foot}</section>`;
|
|
424
|
+
}
|
|
425
|
+
if (composition.profile === 'developer') {
|
|
426
|
+
return `<div>${head}${cover}${grid(toc + prose, 'section')}${foot}</div>`;
|
|
427
|
+
}
|
|
428
|
+
return head + cover + grid(toc + prose) + foot;
|
|
429
|
+
};
|
|
391
430
|
const interactionsModule = interactionsActive(options.interactions)
|
|
392
431
|
? options.interactions
|
|
393
432
|
: undefined;
|
|
@@ -612,13 +651,32 @@ export function buildGeneratedPages(validatedInput, options) {
|
|
|
612
651
|
* @param {string} [afterHtml] markup after the list (pagination)
|
|
613
652
|
* @returns {string}
|
|
614
653
|
*/
|
|
615
|
-
const rowList = (items, afterHtml = '') =>
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
654
|
+
const rowList = (items, afterHtml = '') => {
|
|
655
|
+
const grid = composition.listingLayout === 'image-grid';
|
|
656
|
+
const issueCards = composition.listingLayout === 'issues';
|
|
657
|
+
const datedRows = composition.listingLayout === 'dated-rows';
|
|
658
|
+
const outer =
|
|
659
|
+
composition.profile === 'personal' || composition.profile === 'developer'
|
|
660
|
+
? 'div'
|
|
661
|
+
: 'section';
|
|
662
|
+
const contents =
|
|
663
|
+
items.length > 0
|
|
664
|
+
? datedRows
|
|
665
|
+
? `<div class="g-list g-dated-list">${items
|
|
666
|
+
.map(
|
|
667
|
+
(record) =>
|
|
668
|
+
`<div class="g-dated-row"><time class="g-date-stamp" datetime="${escapeHtml(record.frontmatter.publishedAt)}">` +
|
|
669
|
+
`${call('formatDate', record.frontmatter.publishedAt)}</time>${cardOf(record, 'row', 2)}</div>`,
|
|
670
|
+
)
|
|
671
|
+
.join('')}</div>`
|
|
672
|
+
: `<div class="${grid ? 'g-grid' : 'g-list'}">${items
|
|
673
|
+
.map((record) =>
|
|
674
|
+
cardOf(record, grid || issueCards ? 'grid' : 'row', 2),
|
|
675
|
+
)
|
|
676
|
+
.join('')}</div>`
|
|
677
|
+
: `<p>${text('emptyListingLabel')}</p>`;
|
|
678
|
+
return `<${outer} class="g-wrap g-section" data-gala-listing-layout="${composition.listingLayout}">${contents}${afterHtml}</${outer}>`;
|
|
679
|
+
};
|
|
622
680
|
|
|
623
681
|
/**
|
|
624
682
|
* One listing page's metadata: bare title, `<title>`, description,
|
|
@@ -710,6 +768,28 @@ export function buildGeneratedPages(validatedInput, options) {
|
|
|
710
768
|
? `<p class="g-dek">${escapeHtml(author.biography)}</p>`
|
|
711
769
|
: '') +
|
|
712
770
|
links;
|
|
771
|
+
const authorHead = listingHead({
|
|
772
|
+
breadcrumbHtml: crumbs(
|
|
773
|
+
[{ label: /** @type {string} */ (messages.authorsSectionLabel) }],
|
|
774
|
+
[{ label: author.displayName }],
|
|
775
|
+
),
|
|
776
|
+
kicker: /** @type {string} */ (messages.authorKickerLabel),
|
|
777
|
+
count: authored.length,
|
|
778
|
+
title: author.displayName,
|
|
779
|
+
descriptionHtml: intro,
|
|
780
|
+
markHtml: avatar(author),
|
|
781
|
+
});
|
|
782
|
+
const authoredList = rowList(authored);
|
|
783
|
+
const authorContents =
|
|
784
|
+
composition.profile === 'newsletter'
|
|
785
|
+
? `<section>${authorHead}${authoredList}</section>`
|
|
786
|
+
: composition.profile === 'visual'
|
|
787
|
+
? `<div>${authorHead}<section>${authoredList}</section></div>`
|
|
788
|
+
: composition.profile === 'personal'
|
|
789
|
+
? `<section>${authorHead}<div>${authoredList}</div></section>`
|
|
790
|
+
: composition.profile === 'developer'
|
|
791
|
+
? `<div>${authorHead}<div>${authoredList}</div></div>`
|
|
792
|
+
: authorHead + authoredList;
|
|
713
793
|
pages.push({
|
|
714
794
|
kind: 'author',
|
|
715
795
|
route: authorRoute(author),
|
|
@@ -737,17 +817,9 @@ export function buildGeneratedPages(validatedInput, options) {
|
|
|
737
817
|
}),
|
|
738
818
|
),
|
|
739
819
|
bodyHtml:
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
[{ label: author.displayName }],
|
|
744
|
-
),
|
|
745
|
-
kicker: /** @type {string} */ (messages.authorKickerLabel),
|
|
746
|
-
count: authored.length,
|
|
747
|
-
title: author.displayName,
|
|
748
|
-
descriptionHtml: intro,
|
|
749
|
-
markHtml: avatar(author),
|
|
750
|
-
}) + rowList(authored),
|
|
820
|
+
`<div data-gala-author-layout="${composition.authorLayout}">` +
|
|
821
|
+
authorContents +
|
|
822
|
+
`</div>`,
|
|
751
823
|
});
|
|
752
824
|
}
|
|
753
825
|
|
|
@@ -822,7 +894,7 @@ export function buildGeneratedPages(validatedInput, options) {
|
|
|
822
894
|
editionSelector +
|
|
823
895
|
`</div>`;
|
|
824
896
|
const cover = hero
|
|
825
|
-
? `<figure class="g-wrap g-article-cover">${renderImage({ image: hero, alt: heroMedia?.role === 'decorative' ? '' : (heroMedia?.alt ?? ''), priority: true })}</figure>`
|
|
897
|
+
? `<figure class="${composition.articleLayout === 'full-bleed' ? 'g-article-cover g-article-cover-full-bleed' : 'g-wrap g-article-cover'}">${renderImage({ image: hero, alt: heroMedia?.role === 'decorative' ? '' : (heroMedia?.alt ?? ''), priority: true })}</figure>`
|
|
826
898
|
: '';
|
|
827
899
|
const tocNav = contents
|
|
828
900
|
? `<nav class="g-toc" aria-label="${text('onThisPageLabel')}"><p class="g-label">${icon('list')}${text('onThisPageLabel')}</p>${contents}</nav>`
|
|
@@ -1001,8 +1073,8 @@ export function buildGeneratedPages(validatedInput, options) {
|
|
|
1001
1073
|
interactionBearing: Boolean(interactions),
|
|
1002
1074
|
lastModified: contentLastModified(frontmatter),
|
|
1003
1075
|
bodyHtml:
|
|
1004
|
-
`<article class="g-article">${isArticle || isEdition ? '<div class="g-progress" aria-hidden="true"></div>' : ''}
|
|
1005
|
-
|
|
1076
|
+
`<article class="g-article" data-gala-article-layout="${composition.articleLayout}">${isArticle || isEdition ? '<div class="g-progress" aria-hidden="true"></div>' : ''}` +
|
|
1077
|
+
`${articleStructure({ head, cover, toc: tocNav, prose, foot })}</article>` +
|
|
1006
1078
|
after +
|
|
1007
1079
|
(isArticle ? newsletterHtml : ''),
|
|
1008
1080
|
});
|
|
@@ -1093,15 +1165,49 @@ export function buildGeneratedPages(validatedInput, options) {
|
|
|
1093
1165
|
? `<section class="g-wrap g-section"><div class="g-section-head"><h2>${text('moreArticlesHeading')}</h2></div>` +
|
|
1094
1166
|
`<div class="g-list">${items.map((r) => cardOf(r, 'row')).join('')}</div>${pagination}</section>`
|
|
1095
1167
|
: '';
|
|
1096
|
-
const
|
|
1097
|
-
|
|
1168
|
+
const homeParts =
|
|
1169
|
+
composition.profile === 'newsletter'
|
|
1098
1170
|
? homeHeading +
|
|
1099
|
-
homeFeatured +
|
|
1100
1171
|
homeTags +
|
|
1172
|
+
homeFeatured +
|
|
1101
1173
|
homeLatest +
|
|
1102
|
-
homeSeries +
|
|
1103
1174
|
moreList +
|
|
1175
|
+
homeSeries +
|
|
1104
1176
|
newsletterHtml
|
|
1177
|
+
: composition.profile === 'visual'
|
|
1178
|
+
? homeHeading +
|
|
1179
|
+
homeFeatured +
|
|
1180
|
+
homeLatest +
|
|
1181
|
+
homeSeries +
|
|
1182
|
+
homeTags +
|
|
1183
|
+
moreList +
|
|
1184
|
+
newsletterHtml
|
|
1185
|
+
: composition.profile === 'personal'
|
|
1186
|
+
? homeHeading +
|
|
1187
|
+
homeLatest +
|
|
1188
|
+
homeFeatured +
|
|
1189
|
+
moreList +
|
|
1190
|
+
homeTags +
|
|
1191
|
+
homeSeries +
|
|
1192
|
+
newsletterHtml
|
|
1193
|
+
: composition.profile === 'developer'
|
|
1194
|
+
? homeHeading +
|
|
1195
|
+
homeTags +
|
|
1196
|
+
homeLatest +
|
|
1197
|
+
homeSeries +
|
|
1198
|
+
homeFeatured +
|
|
1199
|
+
moreList +
|
|
1200
|
+
newsletterHtml
|
|
1201
|
+
: homeHeading +
|
|
1202
|
+
homeFeatured +
|
|
1203
|
+
homeTags +
|
|
1204
|
+
homeLatest +
|
|
1205
|
+
homeSeries +
|
|
1206
|
+
moreList +
|
|
1207
|
+
newsletterHtml;
|
|
1208
|
+
const bodyHtml =
|
|
1209
|
+
pageNumber === 1
|
|
1210
|
+
? `<div data-gala-home-layout="${composition.homeLayout}">${homeParts}</div>`
|
|
1105
1211
|
: listingHead({
|
|
1106
1212
|
breadcrumbHtml: crumbs([
|
|
1107
1213
|
{ label: /** @type {string} */ (messages.indexHeading) },
|
|
@@ -0,0 +1,185 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Generation-4 template composition admission.
|
|
3
|
+
*
|
|
4
|
+
* A composition is one complete, immutable product direction. Admission is
|
|
5
|
+
* deliberately by exact object equality so fields from different directions
|
|
6
|
+
* cannot be combined into renderer states that were never designed or tested.
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
/** The immutable generation-4 composition schema identity. */
|
|
10
|
+
export const TEMPLATE_COMPOSITION_SCHEMA_ID =
|
|
11
|
+
'urn:gala:schema:template-composition:2.0.0';
|
|
12
|
+
|
|
13
|
+
const SCHEMA_FIELDS = Object.freeze({
|
|
14
|
+
schemaId: TEMPLATE_COMPOSITION_SCHEMA_ID,
|
|
15
|
+
schemaVersion: '2.0.0',
|
|
16
|
+
});
|
|
17
|
+
|
|
18
|
+
/** The complete Editorial composition. */
|
|
19
|
+
export const EDITORIAL_COMPOSITION = Object.freeze({
|
|
20
|
+
...SCHEMA_FIELDS,
|
|
21
|
+
profile: 'editorial',
|
|
22
|
+
homeLayout: 'magazine',
|
|
23
|
+
articleLayout: 'editorial',
|
|
24
|
+
authorLayout: 'portrait',
|
|
25
|
+
listingLayout: 'rows',
|
|
26
|
+
headerLayout: 'masthead',
|
|
27
|
+
footerLayout: 'expanded',
|
|
28
|
+
mediaRatio: 'landscape',
|
|
29
|
+
density: 'comfortable',
|
|
30
|
+
});
|
|
31
|
+
|
|
32
|
+
/** The complete Newsletter composition. */
|
|
33
|
+
export const NEWSLETTER_COMPOSITION = Object.freeze({
|
|
34
|
+
...SCHEMA_FIELDS,
|
|
35
|
+
profile: 'newsletter',
|
|
36
|
+
homeLayout: 'newspaper',
|
|
37
|
+
articleLayout: 'issue',
|
|
38
|
+
authorLayout: 'profile',
|
|
39
|
+
listingLayout: 'issues',
|
|
40
|
+
headerLayout: 'publication',
|
|
41
|
+
footerLayout: 'expanded',
|
|
42
|
+
mediaRatio: 'landscape',
|
|
43
|
+
density: 'comfortable',
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
/** The complete Visual composition. */
|
|
47
|
+
export const VISUAL_COMPOSITION = Object.freeze({
|
|
48
|
+
...SCHEMA_FIELDS,
|
|
49
|
+
profile: 'visual',
|
|
50
|
+
homeLayout: 'gallery',
|
|
51
|
+
articleLayout: 'full-bleed',
|
|
52
|
+
authorLayout: 'portfolio',
|
|
53
|
+
listingLayout: 'image-grid',
|
|
54
|
+
headerLayout: 'minimal',
|
|
55
|
+
footerLayout: 'compact',
|
|
56
|
+
mediaRatio: 'mixed',
|
|
57
|
+
density: 'comfortable',
|
|
58
|
+
});
|
|
59
|
+
|
|
60
|
+
/** The complete Personal composition. */
|
|
61
|
+
export const PERSONAL_COMPOSITION = Object.freeze({
|
|
62
|
+
...SCHEMA_FIELDS,
|
|
63
|
+
profile: 'personal',
|
|
64
|
+
homeLayout: 'chronological',
|
|
65
|
+
articleLayout: 'prose',
|
|
66
|
+
authorLayout: 'biography',
|
|
67
|
+
listingLayout: 'dated-rows',
|
|
68
|
+
headerLayout: 'compact',
|
|
69
|
+
footerLayout: 'compact',
|
|
70
|
+
mediaRatio: 'landscape',
|
|
71
|
+
density: 'spacious',
|
|
72
|
+
});
|
|
73
|
+
|
|
74
|
+
/** The complete Developer composition. */
|
|
75
|
+
export const DEVELOPER_COMPOSITION = Object.freeze({
|
|
76
|
+
...SCHEMA_FIELDS,
|
|
77
|
+
profile: 'developer',
|
|
78
|
+
homeLayout: 'topic-index',
|
|
79
|
+
articleLayout: 'technical',
|
|
80
|
+
authorLayout: 'biography',
|
|
81
|
+
listingLayout: 'rows',
|
|
82
|
+
headerLayout: 'utility',
|
|
83
|
+
footerLayout: 'compact',
|
|
84
|
+
mediaRatio: 'landscape',
|
|
85
|
+
density: 'compact',
|
|
86
|
+
});
|
|
87
|
+
|
|
88
|
+
/** Every complete composition implemented by generation 4. */
|
|
89
|
+
export const SUPPORTED_COMPOSITIONS = Object.freeze([
|
|
90
|
+
EDITORIAL_COMPOSITION,
|
|
91
|
+
NEWSLETTER_COMPOSITION,
|
|
92
|
+
VISUAL_COMPOSITION,
|
|
93
|
+
PERSONAL_COMPOSITION,
|
|
94
|
+
DEVELOPER_COMPOSITION,
|
|
95
|
+
]);
|
|
96
|
+
|
|
97
|
+
/** @type {Readonly<Record<string, (typeof SUPPORTED_COMPOSITIONS)[number]>>} */
|
|
98
|
+
const COMPOSITION_BY_PROFILE = Object.freeze(
|
|
99
|
+
Object.fromEntries(
|
|
100
|
+
SUPPORTED_COMPOSITIONS.map((composition) => [
|
|
101
|
+
composition.profile,
|
|
102
|
+
composition,
|
|
103
|
+
]),
|
|
104
|
+
),
|
|
105
|
+
);
|
|
106
|
+
|
|
107
|
+
const COMPOSITION_ATTRIBUTE_NAMES = Object.freeze({
|
|
108
|
+
profile: 'data-gala-profile',
|
|
109
|
+
homeLayout: 'data-gala-home-layout',
|
|
110
|
+
articleLayout: 'data-gala-article-layout',
|
|
111
|
+
authorLayout: 'data-gala-author-layout',
|
|
112
|
+
listingLayout: 'data-gala-listing-layout',
|
|
113
|
+
headerLayout: 'data-gala-header-layout',
|
|
114
|
+
footerLayout: 'data-gala-footer-layout',
|
|
115
|
+
mediaRatio: 'data-gala-media-ratio',
|
|
116
|
+
density: 'data-gala-density',
|
|
117
|
+
});
|
|
118
|
+
|
|
119
|
+
/** @typedef {(typeof SUPPORTED_COMPOSITIONS)[number]} SupportedComposition */
|
|
120
|
+
/** @typedef {Exclude<keyof SupportedComposition, 'schemaId' | 'schemaVersion'>} CompositionField */
|
|
121
|
+
|
|
122
|
+
/** Public semantic attribute catalogs corresponding to composition fields. */
|
|
123
|
+
export const COMPOSITION_ATTRIBUTE_CATALOG = Object.freeze(
|
|
124
|
+
/** @type {readonly [CompositionField, string][]} */ (
|
|
125
|
+
Object.entries(COMPOSITION_ATTRIBUTE_NAMES)
|
|
126
|
+
).map(([field, name]) =>
|
|
127
|
+
Object.freeze({
|
|
128
|
+
field,
|
|
129
|
+
name,
|
|
130
|
+
values: Object.freeze([
|
|
131
|
+
...new Set(
|
|
132
|
+
SUPPORTED_COMPOSITIONS.map((composition) => composition[field]),
|
|
133
|
+
),
|
|
134
|
+
]),
|
|
135
|
+
}),
|
|
136
|
+
),
|
|
137
|
+
);
|
|
138
|
+
|
|
139
|
+
/** Every public semantic attribute/value pair themes may select. */
|
|
140
|
+
export const COMPOSITION_ATTRIBUTES = Object.freeze(
|
|
141
|
+
COMPOSITION_ATTRIBUTE_CATALOG.flatMap(({ field, name, values }) =>
|
|
142
|
+
values.map((value) => Object.freeze({ field, name, value })),
|
|
143
|
+
),
|
|
144
|
+
);
|
|
145
|
+
|
|
146
|
+
/**
|
|
147
|
+
* Admit exactly one complete composition implemented by this renderer.
|
|
148
|
+
*
|
|
149
|
+
* @param {unknown} candidate a complete template-composition document
|
|
150
|
+
* @returns {(typeof SUPPORTED_COMPOSITIONS)[number]} canonical composition
|
|
151
|
+
*/
|
|
152
|
+
export function assertSupportedComposition(candidate) {
|
|
153
|
+
if (!candidate || typeof candidate !== 'object' || Array.isArray(candidate)) {
|
|
154
|
+
throw new Error(
|
|
155
|
+
`composition must be a complete ${TEMPLATE_COMPOSITION_SCHEMA_ID} document`,
|
|
156
|
+
);
|
|
157
|
+
}
|
|
158
|
+
const composition = /** @type {Record<string, unknown>} */ (candidate);
|
|
159
|
+
const selected =
|
|
160
|
+
typeof composition.profile === 'string' &&
|
|
161
|
+
Object.hasOwn(COMPOSITION_BY_PROFILE, composition.profile)
|
|
162
|
+
? COMPOSITION_BY_PROFILE[composition.profile]
|
|
163
|
+
: undefined;
|
|
164
|
+
if (!selected) {
|
|
165
|
+
throw new Error(
|
|
166
|
+
`composition.profile (${JSON.stringify(composition.profile)}) is not implemented by this renderer`,
|
|
167
|
+
);
|
|
168
|
+
}
|
|
169
|
+
const expectedKeys = Object.keys(selected).sort();
|
|
170
|
+
const actualKeys = Object.keys(composition).sort();
|
|
171
|
+
if (JSON.stringify(actualKeys) !== JSON.stringify(expectedKeys)) {
|
|
172
|
+
throw new Error(
|
|
173
|
+
`composition must contain exactly ${expectedKeys.join(', ')}`,
|
|
174
|
+
);
|
|
175
|
+
}
|
|
176
|
+
for (const [key, expected] of Object.entries(selected)) {
|
|
177
|
+
if (composition[key] !== expected) {
|
|
178
|
+
throw new Error(
|
|
179
|
+
`composition.${key} (${JSON.stringify(composition[key])}) is not ` +
|
|
180
|
+
`implemented for ${selected.profile}; expected ${JSON.stringify(expected)}`,
|
|
181
|
+
);
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
return selected;
|
|
185
|
+
}
|
|
@@ -85,8 +85,9 @@ import { sanitizeThemeSvg } from './media/theme-svg-sanitizer.js';
|
|
|
85
85
|
import { projectFixedAssetPath } from './route.js';
|
|
86
86
|
import { satisfiesTemplateRange } from './semver-range.js';
|
|
87
87
|
import { escapeHtml } from './skeleton.js';
|
|
88
|
+
import { assertSupportedComposition } from './template-composition.js';
|
|
88
89
|
|
|
89
|
-
/** @type {string} the `urn:gala:schema:theme-contract:2.0.0` schema id
|
|
90
|
+
/** @type {string} the immutable `urn:gala:schema:theme-contract:2.0.0` schema id
|
|
90
91
|
* every consumed `theme.json` is validated against (TPL-H1). */
|
|
91
92
|
const THEME_CONTRACT_SCHEMA_ID = 'urn:gala:schema:theme-contract:2.0.0';
|
|
92
93
|
|
|
@@ -415,7 +416,7 @@ function assertThemeContractIntegrity(themeJson) {
|
|
|
415
416
|
if (!validation.valid) {
|
|
416
417
|
throw new ThemeAssetError(
|
|
417
418
|
'THEME_CONTRACT_SCHEMA_INVALID',
|
|
418
|
-
`theme.json failed
|
|
419
|
+
`theme.json failed ${THEME_CONTRACT_SCHEMA_ID} validation ` +
|
|
419
420
|
`(${validation.diagnostics.length} diagnostic(s)): ` +
|
|
420
421
|
JSON.stringify(validation.diagnostics),
|
|
421
422
|
);
|
|
@@ -458,6 +459,14 @@ function assertThemeContractIntegrity(themeJson) {
|
|
|
458
459
|
`(${TEMPLATE_STYLING_CONTRACT_TEMPLATE_VERSION})`,
|
|
459
460
|
);
|
|
460
461
|
}
|
|
462
|
+
try {
|
|
463
|
+
assertSupportedComposition(themeJson.composition);
|
|
464
|
+
} catch (error) {
|
|
465
|
+
throw new ThemeAssetError(
|
|
466
|
+
'THEME_COMPOSITION_UNSUPPORTED',
|
|
467
|
+
/** @type {Error} */ (error).message,
|
|
468
|
+
);
|
|
469
|
+
}
|
|
461
470
|
}
|
|
462
471
|
|
|
463
472
|
/**
|
|
@@ -490,6 +499,7 @@ function subresourceIntegrityAttribute(bytes) {
|
|
|
490
499
|
* files: {path: string, bytes: Buffer}[],
|
|
491
500
|
* assets: import('../../../types/index.d.ts').ManifestAssetEntry[],
|
|
492
501
|
* linkTagsHtml: string,
|
|
502
|
+
* composition: (typeof import('./template-composition.js').SUPPORTED_COMPOSITIONS)[number],
|
|
493
503
|
* }>} the files to write (already `basePath`-joined), their manifest rows
|
|
494
504
|
* (same joined paths), and the ready-to-insert `<link>` markup
|
|
495
505
|
*/
|
|
@@ -611,7 +621,12 @@ export async function loadThemeAssets({
|
|
|
611
621
|
});
|
|
612
622
|
}
|
|
613
623
|
|
|
614
|
-
return {
|
|
624
|
+
return {
|
|
625
|
+
files,
|
|
626
|
+
assets,
|
|
627
|
+
linkTagsHtml: linkTags.join(''),
|
|
628
|
+
composition: assertSupportedComposition(themeJson.composition),
|
|
629
|
+
};
|
|
615
630
|
}
|
|
616
631
|
|
|
617
632
|
/**
|