diff --git a/README.md b/README.md index c9eea65464..c92ab3a4dc 100644 --- a/README.md +++ b/README.md @@ -77,12 +77,6 @@ They provide an unopinionated, white-label layer that can be extended to your ow Note. There is the same error on master. This issue is not caused by the migration -- There is a browser console error when navigating to [ajax/overview](http://localhost:4321/fundamentals/tools/ajax/overview): - - ``` - __mdjs-stories--overview.js:19 Uncaught TypeError: createCacheInterceptors is not a function or its return value is not iterable - ``` - ### TODO ## How to install diff --git a/config.mjs b/config.mjs new file mode 100644 index 0000000000..e0154abf15 --- /dev/null +++ b/config.mjs @@ -0,0 +1,10 @@ +export const maxDepthForNonComponentsNavigation = 2; +export const docsDirName = '/docs/'; +export const isToBeConcatenated = (path) => { + if (path.includes('/components/')) { + return true; + } + const pathAfterDocs = path.split(docsDirName)[1]; + const numberOfSections = pathAfterDocs.split('/').length; + return numberOfSections > maxDepthForNonComponentsNavigation; +} diff --git a/docs/fundamentals/tools/ajax/overview.md b/docs/fundamentals/tools/ajax/overview.md index 12cc8e17ed..ae62d3f494 100644 --- a/docs/fundamentals/tools/ajax/overview.md +++ b/docs/fundamentals/tools/ajax/overview.md @@ -60,7 +60,7 @@ const cacheOptions = { maxAge: TEN_MINUTES, }; -const [cacheRequestInterceptor, cacheResponseInterceptor] = createCacheInterceptors( +const { cacheRequestInterceptor, cacheResponseInterceptor } = createCacheInterceptors( getCacheIdentifier, cacheOptions, ); diff --git a/docs/fundamentals/tools/ajax/use-cases.md b/docs/fundamentals/tools/ajax/use-cases.md index f6a6820b52..829849ba27 100644 --- a/docs/fundamentals/tools/ajax/use-cases.md +++ b/docs/fundamentals/tools/ajax/use-cases.md @@ -22,7 +22,7 @@ const cacheOptions = { maxAge: TEN_MINUTES, }; -const [cacheRequestInterceptor, cacheResponseInterceptor] = createCacheInterceptors( +const { cacheRequestInterceptor, cacheResponseInterceptor } = createCacheInterceptors( getCacheIdentifier, cacheOptions, ); @@ -191,7 +191,7 @@ const globalCacheOptions = { // for instance when a current user is logged out const getCacheIdentifier = () => getActiveProfile().profileId; -const [cacheRequestInterceptor, cacheResponseInterceptor] = createCacheInterceptors( +const { cacheRequestInterceptor, cacheResponseInterceptor } = createCacheInterceptors( getCacheIdentifier, globalCacheOptions, ); diff --git a/docs/fundamentals/tools/helpers/index.md b/docs/fundamentals/tools/helpers/index.md index e8bfaf1921..1547b8ac19 100644 --- a/docs/fundamentals/tools/helpers/index.md +++ b/docs/fundamentals/tools/helpers/index.md @@ -1,3 +1,3 @@ -# Tools >> Helpers +# Tools >> Helpers ||5 -> go to Overview diff --git a/docs/fundamentals/tools/singleton-manager/example-fail/demo-app.js b/docs/fundamentals/tools/singleton-manager/example-fail/demo-app.js index 802bb6d85c..b561088d1f 100644 --- a/docs/fundamentals/tools/singleton-manager/example-fail/demo-app.js +++ b/docs/fundamentals/tools/singleton-manager/example-fail/demo-app.js @@ -1,7 +1,7 @@ import { LitElement, css, html } from 'lit'; -import 'page-a/page-a.js'; -import 'page-b/page-b.js'; +import 'page-c/page-c.js'; +import 'page-d/page-d.js'; class DemoApp extends LitElement { constructor() { @@ -83,9 +83,9 @@ class DemoApp extends LitElement { Page B - ${this.page === 'A' ? html` ` : html` `} + ${this.page === 'A' ? html` ` : html` `} `; } } -customElements.define('demo-app', DemoApp); +customElements.define('demo-app-fail', DemoApp); diff --git a/docs/fundamentals/tools/singleton-manager/example-fail/index.md b/docs/fundamentals/tools/singleton-manager/example-fail/index.md index 82fe2a50bf..09f719e1fa 100644 --- a/docs/fundamentals/tools/singleton-manager/example-fail/index.md +++ b/docs/fundamentals/tools/singleton-manager/example-fail/index.md @@ -10,7 +10,7 @@ In this SPA (Single Page Application) demo you will be able to reproduce the iss In an real application this would now mean that your users can no longer interact with your application. -Loading App... +Loading App...
diff --git a/docs/fundamentals/tools/singleton-manager/example-fail/node_modules/page-a/package.json b/docs/fundamentals/tools/singleton-manager/example-fail/node_modules/page-c/package.json similarity index 78% rename from docs/fundamentals/tools/singleton-manager/example-fail/node_modules/page-a/package.json rename to docs/fundamentals/tools/singleton-manager/example-fail/node_modules/page-c/package.json index 2c77c4dee3..6f1de33522 100644 --- a/docs/fundamentals/tools/singleton-manager/example-fail/node_modules/page-a/package.json +++ b/docs/fundamentals/tools/singleton-manager/example-fail/node_modules/page-c/package.json @@ -1,5 +1,5 @@ { - "name": "page-a", + "name": "page-c", "version": "1.0.0", "dependencies": { "overlays": "^1.0.0" diff --git a/docs/fundamentals/tools/singleton-manager/example-success/node_modules/page-a/page-a.js b/docs/fundamentals/tools/singleton-manager/example-fail/node_modules/page-c/page-c.js similarity index 90% rename from docs/fundamentals/tools/singleton-manager/example-success/node_modules/page-a/page-a.js rename to docs/fundamentals/tools/singleton-manager/example-fail/node_modules/page-c/page-c.js index 21fd3dde54..7102c89e9c 100644 --- a/docs/fundamentals/tools/singleton-manager/example-success/node_modules/page-a/page-a.js +++ b/docs/fundamentals/tools/singleton-manager/example-fail/node_modules/page-c/page-c.js @@ -1,7 +1,7 @@ import { LitElement, html, css } from 'lit-element'; import { overlays } from 'overlays/instance.js'; -export class PageA extends LitElement { +export class PageC extends LitElement { static get styles() { return css` :host { @@ -31,4 +31,4 @@ export class PageA extends LitElement { } } -customElements.define('page-a', PageA); +customElements.define('page-c', PageC); diff --git a/docs/fundamentals/tools/singleton-manager/example-fail/node_modules/page-b/node_modules/overlays/index.js b/docs/fundamentals/tools/singleton-manager/example-fail/node_modules/page-d/node_modules/overlays/index.js similarity index 100% rename from docs/fundamentals/tools/singleton-manager/example-fail/node_modules/page-b/node_modules/overlays/index.js rename to docs/fundamentals/tools/singleton-manager/example-fail/node_modules/page-d/node_modules/overlays/index.js diff --git a/docs/fundamentals/tools/singleton-manager/example-fail/node_modules/page-b/node_modules/overlays/instance.js b/docs/fundamentals/tools/singleton-manager/example-fail/node_modules/page-d/node_modules/overlays/instance.js similarity index 100% rename from docs/fundamentals/tools/singleton-manager/example-fail/node_modules/page-b/node_modules/overlays/instance.js rename to docs/fundamentals/tools/singleton-manager/example-fail/node_modules/page-d/node_modules/overlays/instance.js diff --git a/docs/fundamentals/tools/singleton-manager/example-fail/node_modules/page-b/node_modules/overlays/package.json b/docs/fundamentals/tools/singleton-manager/example-fail/node_modules/page-d/node_modules/overlays/package.json similarity index 100% rename from docs/fundamentals/tools/singleton-manager/example-fail/node_modules/page-b/node_modules/overlays/package.json rename to docs/fundamentals/tools/singleton-manager/example-fail/node_modules/page-d/node_modules/overlays/package.json diff --git a/docs/fundamentals/tools/singleton-manager/example-fail/node_modules/page-b/package.json b/docs/fundamentals/tools/singleton-manager/example-fail/node_modules/page-d/package.json similarity index 78% rename from docs/fundamentals/tools/singleton-manager/example-fail/node_modules/page-b/package.json rename to docs/fundamentals/tools/singleton-manager/example-fail/node_modules/page-d/package.json index cd0fdbef4a..0bd44f847f 100644 --- a/docs/fundamentals/tools/singleton-manager/example-fail/node_modules/page-b/package.json +++ b/docs/fundamentals/tools/singleton-manager/example-fail/node_modules/page-d/package.json @@ -1,5 +1,5 @@ { - "name": "page-b", + "name": "page-d", "version": "1.0.0", "dependencies": { "overlays": "^2.0.0" diff --git a/docs/fundamentals/tools/singleton-manager/example-fail/node_modules/page-b/page-b.js b/docs/fundamentals/tools/singleton-manager/example-fail/node_modules/page-d/page-d.js similarity index 90% rename from docs/fundamentals/tools/singleton-manager/example-fail/node_modules/page-b/page-b.js rename to docs/fundamentals/tools/singleton-manager/example-fail/node_modules/page-d/page-d.js index 94a90c0c0b..b250a5bc1c 100644 --- a/docs/fundamentals/tools/singleton-manager/example-fail/node_modules/page-b/page-b.js +++ b/docs/fundamentals/tools/singleton-manager/example-fail/node_modules/page-d/page-d.js @@ -1,7 +1,7 @@ import { LitElement, html, css } from 'lit-element'; import { overlays } from 'overlays/instance.js'; -export class PageB extends LitElement { +export class PageD extends LitElement { static get styles() { return css` :host { @@ -31,4 +31,4 @@ export class PageB extends LitElement { } } -customElements.define('page-b', PageB); +customElements.define('page-d', PageD); diff --git a/docs/fundamentals/tools/singleton-manager/example-success/demo-app.js b/docs/fundamentals/tools/singleton-manager/example-success/demo-app.js index 057392db9d..c0cc6598bf 100644 --- a/docs/fundamentals/tools/singleton-manager/example-success/demo-app.js +++ b/docs/fundamentals/tools/singleton-manager/example-success/demo-app.js @@ -2,8 +2,8 @@ import { LitElement, css, html } from 'lit'; import './overlayCompatibility.js'; -import 'page-a/page-a.js'; -import 'page-b/page-b.js'; +import 'page-e/page-e.js'; +import 'page-f/page-f.js'; class DemoApp extends LitElement { constructor() { @@ -85,9 +85,9 @@ class DemoApp extends LitElement { Page B - ${this.page === 'A' ? html` ` : html` `} + ${this.page === 'A' ? html` ` : html` `} `; } } -customElements.define('demo-app', DemoApp); +customElements.define('demo-app-success', DemoApp); diff --git a/docs/fundamentals/tools/singleton-manager/example-success/index.md b/docs/fundamentals/tools/singleton-manager/example-success/index.md index bd93efb9e4..f54dcf8325 100644 --- a/docs/fundamentals/tools/singleton-manager/example-success/index.md +++ b/docs/fundamentals/tools/singleton-manager/example-success/index.md @@ -9,7 +9,7 @@ In this SPA (Single Page Application) demo you will be able to reproduce the sol With this solutions users can not break the app anymore. -Loading App... +Loading App...
diff --git a/docs/fundamentals/tools/singleton-manager/example-success/node_modules/page-a/package.json b/docs/fundamentals/tools/singleton-manager/example-success/node_modules/page-e/package.json similarity index 78% rename from docs/fundamentals/tools/singleton-manager/example-success/node_modules/page-a/package.json rename to docs/fundamentals/tools/singleton-manager/example-success/node_modules/page-e/package.json index 2c77c4dee3..aafc03c19e 100644 --- a/docs/fundamentals/tools/singleton-manager/example-success/node_modules/page-a/package.json +++ b/docs/fundamentals/tools/singleton-manager/example-success/node_modules/page-e/package.json @@ -1,5 +1,5 @@ { - "name": "page-a", + "name": "page-e", "version": "1.0.0", "dependencies": { "overlays": "^1.0.0" diff --git a/docs/fundamentals/tools/singleton-manager/example-fail/node_modules/page-a/page-a.js b/docs/fundamentals/tools/singleton-manager/example-success/node_modules/page-e/page-e.js similarity index 90% rename from docs/fundamentals/tools/singleton-manager/example-fail/node_modules/page-a/page-a.js rename to docs/fundamentals/tools/singleton-manager/example-success/node_modules/page-e/page-e.js index 21fd3dde54..40be7b2fd8 100644 --- a/docs/fundamentals/tools/singleton-manager/example-fail/node_modules/page-a/page-a.js +++ b/docs/fundamentals/tools/singleton-manager/example-success/node_modules/page-e/page-e.js @@ -1,7 +1,7 @@ import { LitElement, html, css } from 'lit-element'; import { overlays } from 'overlays/instance.js'; -export class PageA extends LitElement { +export class PageE extends LitElement { static get styles() { return css` :host { @@ -30,5 +30,4 @@ export class PageA extends LitElement { `; } } - -customElements.define('page-a', PageA); +customElements.define('page-e', PageE); diff --git a/docs/fundamentals/tools/singleton-manager/example-success/node_modules/page-b/node_modules/overlays/index.js b/docs/fundamentals/tools/singleton-manager/example-success/node_modules/page-f/node_modules/overlays/index.js similarity index 100% rename from docs/fundamentals/tools/singleton-manager/example-success/node_modules/page-b/node_modules/overlays/index.js rename to docs/fundamentals/tools/singleton-manager/example-success/node_modules/page-f/node_modules/overlays/index.js diff --git a/docs/fundamentals/tools/singleton-manager/example-success/node_modules/page-b/node_modules/overlays/instance.js b/docs/fundamentals/tools/singleton-manager/example-success/node_modules/page-f/node_modules/overlays/instance.js similarity index 100% rename from docs/fundamentals/tools/singleton-manager/example-success/node_modules/page-b/node_modules/overlays/instance.js rename to docs/fundamentals/tools/singleton-manager/example-success/node_modules/page-f/node_modules/overlays/instance.js diff --git a/docs/fundamentals/tools/singleton-manager/example-success/node_modules/page-b/node_modules/overlays/package.json b/docs/fundamentals/tools/singleton-manager/example-success/node_modules/page-f/node_modules/overlays/package.json similarity index 100% rename from docs/fundamentals/tools/singleton-manager/example-success/node_modules/page-b/node_modules/overlays/package.json rename to docs/fundamentals/tools/singleton-manager/example-success/node_modules/page-f/node_modules/overlays/package.json diff --git a/docs/fundamentals/tools/singleton-manager/example-success/node_modules/page-b/package.json b/docs/fundamentals/tools/singleton-manager/example-success/node_modules/page-f/package.json similarity index 78% rename from docs/fundamentals/tools/singleton-manager/example-success/node_modules/page-b/package.json rename to docs/fundamentals/tools/singleton-manager/example-success/node_modules/page-f/package.json index cd0fdbef4a..a300d09441 100644 --- a/docs/fundamentals/tools/singleton-manager/example-success/node_modules/page-b/package.json +++ b/docs/fundamentals/tools/singleton-manager/example-success/node_modules/page-f/package.json @@ -1,5 +1,5 @@ { - "name": "page-b", + "name": "page-f", "version": "1.0.0", "dependencies": { "overlays": "^2.0.0" diff --git a/docs/fundamentals/tools/singleton-manager/example-success/node_modules/page-b/page-b.js b/docs/fundamentals/tools/singleton-manager/example-success/node_modules/page-f/page-f.js similarity index 90% rename from docs/fundamentals/tools/singleton-manager/example-success/node_modules/page-b/page-b.js rename to docs/fundamentals/tools/singleton-manager/example-success/node_modules/page-f/page-f.js index 41fa08ad45..ba2a7e3b8d 100644 --- a/docs/fundamentals/tools/singleton-manager/example-success/node_modules/page-b/page-b.js +++ b/docs/fundamentals/tools/singleton-manager/example-success/node_modules/page-f/page-f.js @@ -1,7 +1,7 @@ import { LitElement, html, css } from 'lit-element'; import { overlays } from 'overlays/instance.js'; -export class PageB extends LitElement { +export class PageF extends LitElement { static get styles() { return css` :host { @@ -31,4 +31,4 @@ export class PageB extends LitElement { } } -customElements.define('page-b', PageB); +customElements.define('page-f', PageF); diff --git a/docs/fundamentals/tools/singleton-manager/index.md b/docs/fundamentals/tools/singleton-manager/index.md index 6dd7c78445..063b117991 100644 --- a/docs/fundamentals/tools/singleton-manager/index.md +++ b/docs/fundamentals/tools/singleton-manager/index.md @@ -1,3 +1,3 @@ -# Tools >> Singleton Manager ||20 +# Tools >> Singleton Manager ||30 -> go to Overview diff --git a/patches/@astrojs+markdown-remark+3.3.0.patch b/patches/@astrojs+markdown-remark+3.3.0.patch new file mode 100644 index 0000000000..114dced1a3 --- /dev/null +++ b/patches/@astrojs+markdown-remark+3.3.0.patch @@ -0,0 +1,27 @@ +diff --git a/node_modules/@astrojs/markdown-remark/dist/rehype-collect-headings.js b/node_modules/@astrojs/markdown-remark/dist/rehype-collect-headings.js +index 2f1ee5d..6865631 100644 +--- a/node_modules/@astrojs/markdown-remark/dist/rehype-collect-headings.js ++++ b/node_modules/@astrojs/markdown-remark/dist/rehype-collect-headings.js +@@ -1,10 +1,13 @@ + import Slugger from "github-slugger"; + import { visit } from "unist-util-visit"; ++import * as path from 'path'; + import { InvalidAstroDataError, safelyGetAstroData } from "./frontmatter-injection.js"; + const rawNodeTypes = /* @__PURE__ */ new Set(["text", "raw", "mdxTextExpression"]); + const codeTagNames = /* @__PURE__ */ new Set(["code", "pre"]); + function rehypeHeadingIds() { + return function(tree, file) { ++ const fileName = file.history[0]; ++ const parentDirectoryName = path.basename(path.dirname(fileName)); + const headings = []; + const slugger = new Slugger(); + const isMDX = isMDXFile(file); +@@ -52,7 +55,7 @@ function rehypeHeadingIds() { + let slug = slugger.slug(text); + if (slug.endsWith("-")) + slug = slug.slice(0, -1); +- node.properties.id = slug; ++ node.properties.id = `${parentDirectoryName}-${slug}`; + } + headings.push({ depth, slug: node.properties.id, text }); + }); diff --git a/patches/README.md b/patches/README.md new file mode 100644 index 0000000000..6226b88106 --- /dev/null +++ b/patches/README.md @@ -0,0 +1,48 @@ +## @mdjs/core@0.20.0 + +### mdjsStoryParse.js + +The original file URL is here: [URL](https://github.com/modernweb-dev/rocket/blob/%40mdjs/core%400.20.0/packages/mdjs-core/src/mdjsStoryParse.js) + +#### Why + +Astro does not call [mdjsStoryParse](https://github.com/modernweb-dev/rocket/blob/%40mdjs/core%400.20.0/packages/mdjs-core/src/mdjsStoryParse.js#L53) every time an md file is changed while `watching`. The function is called only once. However some [shared variables](https://github.com/modernweb-dev/rocket/blob/%40mdjs/core%400.20.0/packages/mdjs-core/src/mdjsStoryParse.js#L58-L59) are set on the level of the `mdjsStoryParse`. That leads to the situation that those variable are shared among all md files which is not according to the design. The orignal idea is to share those per an md file. As a result when generating `__mdjs-stories.js` files, they get polluted with the data from other files. + +#### About the fix + +- [nodeCodeVisitor](https://github.com/modernweb-dev/rocket/blob/%40mdjs/core%400.20.0/packages/mdjs-core/src/mdjsStoryParse.js#L68) function was moved under the [transformer](https://github.com/modernweb-dev/rocket/blob/%40mdjs/core%400.20.0/packages/mdjs-core/src/mdjsStoryParse.js#L182C18-L182C29) function +- [Shared variables](https://github.com/modernweb-dev/rocket/blob/%40mdjs/core%400.20.0/packages/mdjs-core/src/mdjsStoryParse.js#L58-L59) were moved under the `transformer` function + +This way the shared variables instantiated on every `transformer` function call. + +### mdjsParse.js + +#### Why patching + +Astro does not call [mdjsParse](https://github.com/modernweb-dev/rocket/blob/%40mdjs/core%400.20.0/packages/mdjs-core/src/mdjsParse.js#L7) every time an md file is changed while `watching`. The function is called only once. However some [shared variables](https://github.com/modernweb-dev/rocket/blob/%40mdjs/core%400.20.0/packages/mdjs-core/src/mdjsParse.js#L8) are set on the level of the `mdjsParse`. That leads to the situation that those variable are shared among all md files which is not according to the design. The orignal idea is to share those per an md file. As a result when generating `__mdjs-stories.js` files, they get polluted with the data from other files. + +#### About the patch + +- [Shared variables](https://github.com/modernweb-dev/rocket/blob/%40mdjs/core%400.20.0/packages/mdjs-core/src/mdjsParse.js#L8) were moved under the `transformer` function + +This way the shared variables instantiated on every `transformer` function call. + +### mdjsSetupCode.js + +Dynamic `imports` for `@mdjs/mdjs-preview/define` and `@mdjs/mdjs-story/define` were removed. These imports are inlined into `__mdjs-story.js` by `copyMdjsStories.js` remark plugin. This is done to enable `dist` bundling. + +## @astrojs/markdown-remark + +The patch is done to inhance the `id` naming of tag `HTML` elements. + +### Why updating naming + +In the current implementation of the portal we need to concatenate `md` pages. Astro creates unique values for the `id` attributes for `` tags (`h1`, `h2`, etc. ). The problem is that the `id`'s are not longer unique after concatenation. There might be multiple `overview` `id`'s which is not correct for navigation. + +### What the solution is about + +The solution is to add the parent directory name to the each id as a prefix. That is if the `md` file being parsed is called `docs/tools/my.md` and let's say there is an `h2` tag in with id called `overview`, then after applying patch, the new `id` value becomes `tools-overview`. + +## lit + +The patch is required to make `astro build` work correctly. `lit` is added as an `external` library for the build option in `astro.config.mjs`. And without the patch the build throws errors. diff --git a/src/pages/[top]/[...slug].astro b/src/pages/[top]/[...slug].astro index 92fdc96013..51c476799b 100644 --- a/src/pages/[top]/[...slug].astro +++ b/src/pages/[top]/[...slug].astro @@ -1,9 +1,19 @@ --- +import { glob } from 'glob' +import * as fs from 'fs'; +import * as process from 'process'; import MainLayout from '../../layouts/MainLayout.astro'; +import { UIPortalInpageNav } from "../../components/ui-portal-inpage-nav.js"; import * as path from 'path'; -import { fundamentalsEntries } from '../../content'; +import { fundamentalsEntries, allPages } from '../../content'; import { blogEntries } from '../../content'; import { guideEntries } from '../../content'; +import { maxDepthForNonComponentsNavigation } from '../../../config.mjs'; + +let pages = []; +const inPageNavData = []; +let mdjsStoriesJsPath = ''; +let dirPath; export async function getStaticPaths() { @@ -31,27 +41,255 @@ export async function getStaticPaths() { props: { entry }, })); - return [...fundamentalsArr, ...blogArr, ...guideArr]; + const dirArr = allPages + .filter(entry => { + const separator = '/'; + const dirPath = path.dirname(entry.slug); + const dirParts = dirPath.split(separator); + + return dirParts.length >= maxDepthForNonComponentsNavigation && dirParts[0] !== 'components'; + }) + .map(entry => { + const separator = '/'; + const dirPath = path.dirname(entry.slug); + const dirParts = dirPath.split(separator); + dirParts.splice(maxDepthForNonComponentsNavigation); + const result = { + params: { + top: dirParts.shift(), + slug: dirParts.join(separator) + }, + }; + return result; + }); + + const uniqueDirArr = []; + dirArr.forEach(route => { + if (!uniqueDirArr.find(uniqueRoute => uniqueRoute.params.top === route.params.top && uniqueRoute.params.slug === route.params.slug)) { + uniqueDirArr.push(route); + } + }); + + return [...fundamentalsArr, ...blogArr, ...guideArr, ...dirArr]; } const { entry } = Astro.props; -const { Content } = await entry.render(); -const blogData = Astro.props.entry.data; +const renderDir = async (directoryPath) => { + const entries = getEntriesByDir(directoryPath); + return await concatenateEntries(entries); +}; + +const convertHeadingsToInPageNavData = (headings, componentSlug) => { + const arePagesConcatenated = !entry; + let mainPathPart = arePagesConcatenated ? dirPath : componentSlug; + return headings.map(header => { + const anchor = header.slug; + return { + name: header.text, + url: `/${mainPathPart}#${anchor}` + }; + }); +}; + +const parseEntries = async (entries) => { + const contents = []; + for (const componentEntry of entries) { + const { Content, headings, remarkPluginFrontmatter } = await componentEntry.render(); + const order = remarkPluginFrontmatter.order; + const slug = componentEntry.slug; + const content = {Content, headings, order, slug}; + contents.push(content); + } + return contents; +}; + +const updateHeadings = (contentItems) => { + const parentDirToNavDataMap = new Map(); + for (const contentItem of contentItems) { + const headersH2 = contentItem.headings.filter(header => header.depth === 2); + const parentDirName = path.dirname(contentItem.slug); + if (headersH2.length !== 0) { + const entryInPageNavData = convertHeadingsToInPageNavData(headersH2, contentItem.slug)[0]; + const headersH3 = contentItem.headings.filter(header => header.depth === 3); + if (headersH3.length !== 0) { + entryInPageNavData.children = convertHeadingsToInPageNavData(headersH3, contentItem.slug); + } + inPageNavData.push(entryInPageNavData); + parentDirToNavDataMap.set(parentDirName, entryInPageNavData); + } else { + const headersH3 = contentItem.headings.filter(header => header.depth === 3); + if (headersH3.length !== 0) { + const entryInPageNavData = parentDirToNavDataMap.get(parentDirName); + if (entryInPageNavData) { + entryInPageNavData.children = entryInPageNavData.children || []; + entryInPageNavData.children = [...entryInPageNavData.children, ...convertHeadingsToInPageNavData(headersH3, contentItem.slug)]; + } + } + } + } +}; + +const directoriesOrder = new Map(); +function getOrder(content, contents) { + const dir = path.dirname(content.slug); + const dirIndex = path.join(dir, 'dir-index'); + let dirOrder; + if (directoriesOrder.has(dir)) { + dirOrder = directoriesOrder.get(dir); + } else { + dirOrder = contents.find(item => item.slug === dirIndex).order; + directoriesOrder.set(dir, dirOrder); + } + return dirOrder; +} + +function getContentsWithParentDepth(contents, parentDepth) { + return contents.filter(content => { + const dirDepth = path.dirname(content.slug).split('/').length; + return dirDepth >= parentDepth; + }); +} + +function getSlugForParentDepth(slug, depth) { + const slugParts = slug.split('/'); + const slugPartsForParentDepth = slugParts.slice(0, depth); + return slugPartsForParentDepth.join('/'); +} + +function getUniqueParentDirs(contents, parentDepth) { + const dirs = new Set(); + contents.forEach(content => { + dirs.add(getSlugForParentDepth(content.slug, parentDepth)); + }); + return [...dirs]; +} + +function sortDirs(dirs, contents) { + dirs.sort((a, b) => { + const aDirOrder = contents.find(content => content.slug === path.join(a, 'dir-index')).order; + const bDirOrder = contents.find(content => content.slug === path.join(b, 'dir-index')).order; + return aDirOrder < bDirOrder ? -1 : 1; + }); +} + +function sortDirectoriesForParentDepth(contents, parentDepth) { + + const reducedContents = getContentsWithParentDepth(contents, parentDepth); + + const uniqueParentDirs = getUniqueParentDirs(reducedContents, parentDepth); + + sortDirs(uniqueParentDirs, reducedContents); + contents.sort((a, b) => { + const aParentDir = getSlugForParentDepth(a.slug, parentDepth); + const bParentDir = getSlugForParentDepth(b.slug, parentDepth); + if (uniqueParentDirs.indexOf(aParentDir) > uniqueParentDirs.indexOf(bParentDir)) { + return 1; + } else if (uniqueParentDirs.indexOf(aParentDir) < uniqueParentDirs.indexOf(bParentDir)) { + return -1; + } else { + return 0; + } + }); +} + +function sortDirectories(contents) { + let parentDepth = maxDepthForNonComponentsNavigation + 1; + let hasParentWithDepth = contents.some(content => path.dirname(content.slug).split('/').length === parentDepth); + + while(hasParentWithDepth) { + sortDirectoriesForParentDepth(contents, parentDepth); + parentDepth++; + hasParentWithDepth = contents.some(content => path.dirname(content.slug).split('/').length === parentDepth); + } +} + +function sort(contents) { + contents.sort((a, b) => { + // Get paths with fewer depth first + if (a.slug.split('/').length < b.slug.split('/').length) { + return -1; + } else if (a.slug.split('/').length > b.slug.split('/').length) { + return 1; + } + // same depth + else { + // same parent + if (path.dirname(a.slug) === path.dirname(b.slug)) { + if (path.basename(a.slug) === 'dir-index') { + return -1; + } else if (path.basename(b.slug) === 'dir-index') { + return 1; + } else { + return a.order < b.order ? -1 : 1; + } + } + } + }); +} + +async function concatenateEntries(entries) { + const contents = await parseEntries(entries); + sortDirectories(contents); + sort(contents); + updateHeadings(contents); + return contents; +} + +const getEntriesByDir = (dirname) => { + //return allPages.filter(childEntry => childEntry.slug.startsWith(dirname)); + return allPages.filter(childEntry => { + return childEntry.slug.startsWith(dirname)}); +}; + +const getMdjsStories = (fullDirPath) => { + return new Promise((resolve, reject) => { + glob(fullDirPath + '/**/__mdjs-stories--*.js', {}, (err, files)=>{ + const relativePaths = files.map(file => { + return path.relative(fullDirPath, file); + }); + resolve(relativePaths); + }) + }); +}; + +if (entry) { + pages = await concatenateEntries([entry]); +} else { + dirPath = path.join(Astro.params.top, Astro.params.slug); + pages = await renderDir(dirPath); + const fullDirPath = path.join(process.cwd(), 'public/docs', dirPath); + const files = await getMdjsStories(fullDirPath); + let imports = ''; + files.forEach(file => { + imports += `import('./${file}');\n` + }); + if (imports) { + mdjsStoriesJsPath = path.join(fullDirPath, '__mdjs-stories.js'); + fs.writeFileSync(mdjsStoriesJsPath, imports, 'utf8'); + } +} + +const getPathMdjsStroriesFile = () => { + if (entry) { + const mdjsStroriesFileDirectory = path.dirname(entry.slug); + return `/docs/${mdjsStroriesFileDirectory}/__mdjs-stories--${path.basename(entry.slug)}.js`; + } + if (mdjsStoriesJsPath) { + return '/docs' + mdjsStoriesJsPath.split('/docs')[1]; + } + return null; +} -const getPathMdjsStroriesFile = (entry) => { - const mdjsStroriesFileDirectory = path.dirname(entry.slug); - return `/docs/${mdjsStroriesFileDirectory}/__mdjs-stories.js`; -} --- - - {blogData.title} - {blogData.description} - {blogData.date} - {blogData.tags} - {blogData.author} - + + + { + pages.map((page) => ( + + )) + } - + {getPathMdjsStroriesFile() && } diff --git a/src/pages/components/[component].astro b/src/pages/components/[component].astro index 3ea513bc25..afdfd3f00a 100644 --- a/src/pages/components/[component].astro +++ b/src/pages/components/[component].astro @@ -17,7 +17,6 @@ export async function getStaticPaths() { const { entry } = Astro.props; const componentEntries = getComponentEntries(entry.data.component); const inPageNavData = []; -const contents = []; const convertHeadingsToInPageNavData = (headings, componentSlug) => { return headings.map(header => ({ @@ -26,28 +25,48 @@ const convertHeadingsToInPageNavData = (headings, componentSlug) => { })); }; -const parseEntries = async () => { - for (const componentEntry of componentEntries) { +const parseEntries = async (entries) => { + const contents = []; + for (const componentEntry of entries) { const { Content, headings, remarkPluginFrontmatter } = await componentEntry.render(); const order = remarkPluginFrontmatter.order; const slug = componentEntry.slug; contents.push({Content, headings, order, slug}); } + return contents; }; const updateHeadings = (contentItems) => { for (const contentItem of contentItems) { const headersH2 = contentItem.headings.filter(header => header.depth === 2); + if (headersH2.length === 0) { + continue; + } const entryInPageNavData = convertHeadingsToInPageNavData(headersH2, contentItem.slug)[0]; const headersH3 = contentItem.headings.filter(header => header.depth === 3); - entryInPageNavData.children = convertHeadingsToInPageNavData(headersH3, contentItem.slug); + if (headersH3.length !== 0) { + entryInPageNavData.children = convertHeadingsToInPageNavData(headersH3, contentItem.slug); + } inPageNavData.push(entryInPageNavData); } }; -await parseEntries(); -contents.sort((a, b) => a.order < b.order ? -1 : 1); -updateHeadings(contents); +async function concatenateEntries(entries) { + const contents = await parseEntries(entries); + contents.sort((a, b) => { + if (path.basename(a.slug) === 'dir-index') { + return -1; + } else if (path.basename(b.slug) === 'dir-index') { + return 1; + } else { + return a.order < b.order ? -1 : 1; + } + }); + updateHeadings(contents); + return contents; +} + +const pages = await concatenateEntries(componentEntries); const getPathMdjsStroriesFile = (entry) => { @@ -60,8 +79,8 @@ const getPathMdjsStroriesFile = (entry) => { { - contents.map((content) => ( - + pages.map((page) => ( + )) } diff --git a/src/utils/copy-docs/copy-docs.js b/src/utils/copy-docs/copy-docs.js index 9a07ae0f8b..22082a48a2 100644 --- a/src/utils/copy-docs/copy-docs.js +++ b/src/utils/copy-docs/copy-docs.js @@ -65,13 +65,6 @@ async function processImportsForFile(filePath) { await fs.writeFile(filePath, newSource); } -const createComponentMdFrontmatter = (componentName, order) => { - const componentFrontmatter = `--- -component: ${componentName}`; - const orderFrontmatter = order ? `\norder: ${order}` : ''; - return `${componentFrontmatter + orderFrontmatter}\n---\n\n`; -}; - async function createInfoMd(componentDirectoryPath) { const componentName = path.basename(componentDirectoryPath); const infoMd = `--- @@ -84,6 +77,55 @@ description: ${componentName} description await fs.writeFile(infoMdFilePath, infoMd); } +function getFrontmatter(text) { + const result = {}; + if (!text.startsWith('---')) { + return result; + } + const frontmatterRegex = /---\n(.+?)\n---/gs; + const match = text.matchAll(frontmatterRegex); + const matchResult = [...match]?.[0]?.[1] || ''; + if (matchResult) { + matchResult.split('\n').forEach(pair => { + const pairArr = pair.split(':'); + const key = pairArr[0].trim(); + const value = pairArr[1].trim(); + result[key] = value; + }); + } + return result; +} + +function getContent(text) { + if (Object.keys(getFrontmatter(text)).length === 0) { + return text; + } + const frontmatterRegex = /---\n(.+?)\n---\n(.*)/gs; + const match = text.matchAll(frontmatterRegex); + return [...match]?.[0]?.[2] || text; +} + +function frontmatterToString(frontmatter) { + const prefix = '---\n'; + let result = prefix; + Object.keys(frontmatter).forEach(key => { + result += `${key}: ${frontmatter[key]}\n`; + }); + if (result === prefix) { + return ''; + } + return `${result}---\n\n`; +} + +function addFrontmatter(fileContent, key, value) { + const frontmatter = getFrontmatter(fileContent); + const content = getContent(fileContent); + if (value) { + frontmatter[key] = value; + } + return frontmatterToString(frontmatter) + content; +} + function getOrder(fileContent) { const orderRegexp = /#.+\|\|(\d+)/gm; const match = fileContent.matchAll(orderRegexp); @@ -95,7 +137,10 @@ async function copyDocs(currentPath = '') { for (const file of files) { const sourceDocsFilePath = path.join(sourceDocsPath, currentPath, file); - const contentDocsFilePath = path.join(contentDocsPath, currentPath, file); + const contentDocsFilePath = + file === 'index.md' + ? path.join(contentDocsPath, currentPath, 'dir-index.md') + : path.join(contentDocsPath, currentPath, file); const publicDocsFilePath = path.join(publicDocsPath, currentPath, file); const stats = await fs.lstat(sourceDocsFilePath); @@ -106,20 +151,20 @@ async function copyDocs(currentPath = '') { await copyDocs(path.join(currentPath, file)); } else { if ( - (path.extname(file) === '.md' && file !== 'index.md') || + (path.extname(file) === '.md' && sourceDocsFilePath !== `${sourceDocsPath}/index.md`) || imageExtensions.includes(path.extname(file).split('.')[1]) ) { await fs.mkdir(path.join(contentDocsPath, currentPath), { recursive: true }); await fs.copyFile(sourceDocsFilePath, contentDocsFilePath); - - if (contentDocsFilePath.includes('/components') && path.extname(file) === '.md') { + if (path.extname(file) === '.md') { const fileContent = await fs.readFile(contentDocsFilePath, 'utf8'); - const parentComponent = path.basename(currentPath); + let updatedFileContent = fileContent; + if (contentDocsFilePath.includes('/components')) { + const parentComponent = path.basename(currentPath); + updatedFileContent = addFrontmatter(fileContent, 'component', parentComponent); + } const order = getOrder(fileContent); - const updatedFileContent = `${createComponentMdFrontmatter( - parentComponent, - order, - )}${fileContent}`; + updatedFileContent = addFrontmatter(updatedFileContent, 'order', order); await fs.writeFile(contentDocsFilePath, updatedFileContent); } } @@ -143,7 +188,10 @@ async function copyDocsByFileArray(files) { if (file.includes('/components')) { const fileContent = await fs.readFile(contentDocsFilePath, 'utf8'); const parentComponent = path.basename(currentPath); - const updatedFileContent = `${createComponentMdFrontmatter(parentComponent)}${fileContent}`; + let updatedFileContent = fileContent; + updatedFileContent = addFrontmatter(fileContent, 'component', parentComponent); + const order = getOrder(fileContent); + updatedFileContent = addFrontmatter(updatedFileContent, 'order', order); await fs.writeFile(contentDocsFilePath, updatedFileContent); } } diff --git a/src/utils/remark-plugings/cleanupRocketMetadata/cleanupRocketMetadata.js b/src/utils/remark-plugings/cleanupRocketMetadata/cleanupRocketMetadata.js index 3e25dfc66c..6ab602a02a 100644 --- a/src/utils/remark-plugings/cleanupRocketMetadata/cleanupRocketMetadata.js +++ b/src/utils/remark-plugings/cleanupRocketMetadata/cleanupRocketMetadata.js @@ -1,46 +1,82 @@ // eslint-disable-next-line import/no-extraneous-dependencies const { init } = require('es-module-lexer'); +const path = require('path'); +let isToBeConcatenated; +let maxDepthForNonComponentsNavigation; +let docsDirName; let visit; (async () => { // eslint-disable-next-line import/no-extraneous-dependencies const result = await import('unist-util-visit'); visit = result.visit; + + const config = await import('../../../../config.mjs'); + isToBeConcatenated = config.isToBeConcatenated; + maxDepthForNonComponentsNavigation = config.maxDepthForNonComponentsNavigation; + docsDirName = config.docsDirName; })(); +// function addOverviewTitleToIndexMd(tree, isIndexMd) { +// let h1Index = null; +// tree.children.forEach((item, index) => { +// if (item.depth === 1 && item.type === 'heading' && isIndexMd) { +// h1Index = index; +// } +// }); +// if (h1Index !== null) { +// tree.children.splice(1, 0, { +// type: 'heading', +// depth: 2, +// children: [ +// { +// type: 'text', +// value: 'Index', +// }, +// ], +// }); +// } +// } + function cleanupRocketMetadata() { /** * @param {Node} tree */ - async function transformer(tree) { + async function transformer(tree, file) { + const filePath = file.history[0]; + const isIndexMd = path.basename(filePath) === 'dir-index.md'; + const filePathFromProjectRoot = filePath.split(docsDirName)[1]; + const depthDelta = + path.dirname(filePathFromProjectRoot).split('/').length - maxDepthForNonComponentsNavigation; + /** * @param {UnistNode} _node */ async function nodeCodeVisitor(_node, index, parent) { - if (parent.type === 'heading') { + if (parent.type === 'heading' && isToBeConcatenated(filePath)) { if (parent.depth === 1) { const splitByOrder = _node.value.split('||'); - if (splitByOrder.length === 1) { - return; - } - const order = splitByOrder[1].trim(); - if (!order) { - return; - } const splitByArrows = splitByOrder[0].split('>>'); const title = splitByArrows[splitByArrows.length - 1].trim(); // eslint-disable-next-line no-param-reassign _node.value = title; + if (isIndexMd) { + if (depthDelta > 0) { + // eslint-disable-next-line no-param-reassign + parent.depth += depthDelta; + } + return; + } } // eslint-disable-next-line no-param-reassign - parent.depth += 1; + parent.depth += 1 + depthDelta; } } // unifiedjs expects node changes to be made on the given node... await init; - visit(tree, 'text', nodeCodeVisitor); - + visit(tree, ['text', 'inlineCode'], nodeCodeVisitor); + // addOverviewTitleToIndexMd(tree, isIndexMd); return tree; } diff --git a/src/utils/remark-plugings/copyMdjsStories/copyMdjsStories.js b/src/utils/remark-plugings/copyMdjsStories/copyMdjsStories.js index 99a0082788..50ea208d9f 100644 --- a/src/utils/remark-plugings/copyMdjsStories/copyMdjsStories.js +++ b/src/utils/remark-plugings/copyMdjsStories/copyMdjsStories.js @@ -76,7 +76,11 @@ function copyMdjsStories() { * @param {UnistNode} _node */ async function nodeCodeVisitor(_node, index, parent) { - if (parent.type === 'heading' && parent.depth === 1) { + if ( + parent.type === 'heading' && + parent.depth === 1 && + currentMarkdownFile.includes('/components') + ) { const commonMdjsStoriesFileName = `${pathToMdDirectoryInPublic}/${mdJsStoriesFileName}`; let commonMdjsStoriesContent = ''; try { @@ -85,12 +89,7 @@ function copyMdjsStories() { // noop. File is not yet created for the component } - let exportCmd; - if (isDistBuild) { - exportCmd = `import('./${currentMarkdownFileMdJsStoryName}');\n`; - } else { - exportCmd = `export * from './${currentMarkdownFileMdJsStoryName}';\n`; - } + const exportCmd = `import('./${currentMarkdownFileMdJsStoryName}');\n`; if (commonMdjsStoriesContent.indexOf(exportCmd) === -1) { fs.writeFileSync(commonMdjsStoriesFileName, commonMdjsStoriesContent + exportCmd, 'utf8'); } @@ -115,7 +114,7 @@ function copyMdjsStories() { } let parsedSetupJsCode; - // This is move out off @mdjs/core/src/mdjsSetupCode.js + // This is copied from @mdjs/core/src/mdjsSetupCode.js const initialImprorts = ` import '@mdjs/mdjs-preview/define'; import '@mdjs/mdjs-story/define'; \n`;