diff --git a/scripts/build.cli.js b/scripts/build.cli.js index 10ec50bf..6c700b16 100644 --- a/scripts/build.cli.js +++ b/scripts/build.cli.js @@ -74,5 +74,5 @@ Promise.all(builds.map(([entries, outfile]) => { shell.mkdir('-p', SEARCH_LANGS_OUTPUT); shell.cp('-f', SEARCH_API, SEARCH_API_OUTPUT); - shell.cp('-f', join(dirname(SEARCH_LANGS), '*'), SEARCH_LANGS_OUTPUT); + shell.cp('-f', join(dirname(SEARCH_LANGS), '*.js'), SEARCH_LANGS_OUTPUT); }); diff --git a/src/pages/document.ts b/src/pages/document.ts index 73bdc0d3..2a359239 100644 --- a/src/pages/document.ts +++ b/src/pages/document.ts @@ -3,7 +3,7 @@ import {join} from 'path'; import {BUNDLE_FOLDER, CARRIAGE_RETURN, CUSTOM_STYLE, RTL_LANGS} from '../constants'; import {LeadingPage, Resources, TextItems, VarsMetadata} from '../models'; import {ArgvService, PluginService} from '../services'; -import {getDepthPath} from '~/utils'; +import {getDepthPath} from '../utils'; import {DocInnerProps, DocPageData, render} from '@diplodoc/client/ssr'; import manifest from '@diplodoc/client/manifest'; diff --git a/src/services/search.ts b/src/services/search.ts index 5c2edf44..cafd028c 100644 --- a/src/services/search.ts +++ b/src/services/search.ts @@ -67,8 +67,8 @@ async function release() { const dir = outputDir(lang); mkdirSync(dir, {recursive: true}); - writeFileSync(indexLink(lang), index, 'utf8'); - writeFileSync(registryLink(lang), registry, 'utf8'); + writeFileSync(indexLink(lang), index as string, 'utf8'); + writeFileSync(registryLink(lang), registry as string, 'utf8'); writeFileSync(pageLink(lang), generateStaticSearch(lang as Lang), 'utf8'); if (isLocalSearchEnabled() && langs.includes(lang)) { diff --git a/src/steps/processPages.ts b/src/steps/processPages.ts index 4c6a554e..501d35fb 100644 --- a/src/steps/processPages.ts +++ b/src/steps/processPages.ts @@ -171,7 +171,7 @@ async function saveSinglePages() { relativeTocDir, ); - const toc = TocService.getForPath(relativeTocDir + '/toc.yaml')[1] as YfmToc; + const toc = TocService.getForPath(join(relativeTocDir, 'toc.yaml'))[1] as YfmToc; const lang = configLang ?? Lang.RU; const langs = configLangs?.length ? configLangs : [lang]; @@ -197,7 +197,7 @@ async function saveSinglePages() { const singlePageContent = generateStaticMarkup( pageData, join(relativeTocDir, 'single-page-toc'), - toc.title as string || '', + (toc.title as string) || '', ); writeFileSync(singlePageFn, singlePageContent); diff --git a/src/utils/singlePage.ts b/src/utils/singlePage.ts index eeff9dd1..343bcf5b 100644 --- a/src/utils/singlePage.ts +++ b/src/utils/singlePage.ts @@ -25,14 +25,18 @@ function relativeTo(root: string, path: string) { root = toUrl(root); path = toUrl(path); - return path.replace(root + '/', ''); + if (root && path.startsWith(root + '/')) { + path = path.replace(root + '/', ''); + } + + return path; } function all(root: HTMLElement, selector: string): HTMLElement[] { return Array.from(root.querySelectorAll(selector)); } -function decreaseHeadingLevels(root: HTMLElement) { +export function decreaseHeadingLevels(root: HTMLElement) { const headersSelector = 'h1, h2, h3, h4, h5'; root.querySelectorAll(headersSelector).forEach((node) => { @@ -43,7 +47,7 @@ function decreaseHeadingLevels(root: HTMLElement) { }); } -function tryFixFirstPageHeader(root: HTMLElement) { +export function tryFixFirstPageHeader(root: HTMLElement) { const firstPageHeader = root.querySelector(HEADERS_SELECTOR); if (!firstPageHeader || firstPageHeader.rawTagName === 'h1') { return; @@ -52,19 +56,20 @@ function tryFixFirstPageHeader(root: HTMLElement) { firstPageHeader.rawTagName = 'h1'; } -function replaceLinks(rootEl: HTMLElement, options: PreprocessSinglePageOptions) { +export function replaceLinks(root: HTMLElement, options: PreprocessSinglePageOptions) { const {path, tocDir} = options; - for (const node of all(rootEl, 'a:not(.yfm-anchor):not([target="_blank"])')) { + for (const node of all(root, 'a:not(.yfm-anchor):not([target="_blank"])')) { const href = node.getAttribute('href') || ''; const linkFullPath = join(dirname(path), href); - // TODO: This is wrong check + // TODO: isLinkOutOfToc is wrong check // we need to to something like TocService.getForPath // and then compare with local toc path. const isLinkOutOfToc = !linkFullPath.startsWith(tocDir); + const isLinkOutOfRoot = linkFullPath.startsWith('../'); - if (isLinkOutOfToc) { + if (isLinkOutOfToc || isLinkOutOfRoot) { return; } @@ -80,12 +85,12 @@ function prepareAnchorAttrs(node: HTMLElement, pathname: string, page: string) { } if (name === 'id') { - node.setAttribute(name, `#${page}_${value}`); + node.setAttribute(name, `${page}_${value}`); } } } -function addPagePrefixToAnchors(root: HTMLElement, options: PreprocessSinglePageOptions) { +export function addPagePrefixToAnchors(root: HTMLElement, options: PreprocessSinglePageOptions) { const {path, tocDir} = options; const url = getSinglePageUrl(tocDir, path); @@ -111,18 +116,29 @@ function addPagePrefixToAnchors(root: HTMLElement, options: PreprocessSinglePage } } -function addMainTitle(root: HTMLElement, options: PreprocessSinglePageOptions) { +export function addMainTitle(root: HTMLElement, options: PreprocessSinglePageOptions) { if (options.title) { root.insertAdjacentHTML('afterbegin', `

${options.title}

`); } } function getAnchorId(tocDir: string, path: string) { - return relativeTo(tocDir, toUrl(dropExt(path))).replace(/[#/]/g, '_'); + const [pathname, hash] = path.split('#'); + const url = toUrl(dropExt(pathname)) + (hash ? '#' + hash : ''); + + // TODO: encodeURIComponent will be best option + return relativeTo(tocDir, url.replace(/\.\.\/|[/#]/g, '_')); } export function getSinglePageUrl(tocDir: string, path: string) { - return toUrl(tocDir) + '/single-page.html#' + getAnchorId(tocDir, path); + const prefix = toUrl(tocDir) || '.'; + const suffix = getAnchorId(tocDir, path); + + if (prefix === '.') { + return '#' + suffix; + } + + return prefix + '/single-page.html#' + suffix; } export function joinSinglePageResults( diff --git a/tests/e2e/__snapshots__/include-toc.test.ts.snap b/tests/e2e/__snapshots__/include-toc.test.ts.snap index ec4d957b..9224ba56 100644 --- a/tests/e2e/__snapshots__/include-toc.test.ts.snap +++ b/tests/e2e/__snapshots__/include-toc.test.ts.snap @@ -38,8 +38,6 @@ exports[`Include toc Nested toc inclusions with mixed including modes 4`] = ` items: - name: Article1 href: article1.md -base: product1 -deepBase: 1 " `; @@ -121,8 +119,6 @@ items: items: - name: Article1 href: overlay3/article1.md -base: product2 -deepBase: 1 " `; @@ -162,8 +158,6 @@ exports[`Include toc Toc is included in link mode 5`] = ` items: - name: A1 href: folder1/folder2/a1.md -base: . -deepBase: 0 " `; @@ -291,8 +285,6 @@ exports[`Include toc Toc is included inline, not as a new section 12`] = ` href: fileC.md - name: NameX href: fileX.md -base: . -deepBase: 0 " `; @@ -328,7 +320,5 @@ href: index.yaml items: - name: A1 href: a1.md -base: . -deepBase: 0 " `; diff --git a/tests/e2e/__snapshots__/load-custom-resources.spec.ts.snap b/tests/e2e/__snapshots__/load-custom-resources.spec.ts.snap index a807bad3..f23d6850 100644 --- a/tests/e2e/__snapshots__/load-custom-resources.spec.ts.snap +++ b/tests/e2e/__snapshots__/load-custom-resources.spec.ts.snap @@ -47,6 +47,7 @@ exports[`Allow load custom resources md2html single page with custom resources 1 "index.html", "page.html", "project/config.html", + "single-page-toc.js", "single-page.html", "single-page.json", "toc.js" @@ -99,9 +100,9 @@ exports[`Allow load custom resources md2html single page with custom resources 2 - @@ -164,11 +165,11 @@ exports[`Allow load custom resources md2html single page with custom resources 3 - @@ -228,11 +229,11 @@ exports[`Allow load custom resources md2html single page with custom resources 4 - @@ -252,19 +253,21 @@ exports[`Allow load custom resources md2html single page with custom resources 4 `; -exports[`Allow load custom resources md2html single page with custom resources 5`] = ` +exports[`Allow load custom resources md2html single page with custom resources 5`] = `"window.__DATA__.data.toc = {"title":"Documentation","href":"#index","items":[{"name":"Documentation","href":"#page","id":"Documentation-RANDOM"},{"name":"Config","href":"#project_config","id":"Config-RANDOM"}]};"`; + +exports[`Allow load custom resources md2html single page with custom resources 6`] = ` - + - undefined + Documentation @@ -247,22 +247,22 @@ exports[`Generate html document with correct lang and dir attributes. Load corre - @@ -276,7 +276,7 @@ exports[`Generate html document with correct lang and dir attributes. Load corre > - + @@ -290,11 +290,11 @@ exports[`Generate html document with correct lang and dir attributes. Load corre @@ -302,31 +302,31 @@ exports[`Generate html document with correct lang and dir attributes. Load corre - `; -exports[`Generate html document with correct lang and dir attributes. Load correct bundles. documentation with rtl and ltr langs 4`] = `"window.__DATA__.data.toc = {"title":"Documentation","href":"index.html","items":[{"name":"Documentation","href":"page.html","id":"Documentation-RANDOM"}],"base":"ar","deepBase":1};"`; +exports[`Generate html document with correct lang and dir attributes. Load correct bundles. documentation with rtl and ltr langs 4`] = `"window.__DATA__.data.toc = {"title":"Documentation","href":"ar/index.html","items":[{"name":"Documentation","href":"ar/page.html","id":"Documentation-RANDOM"}]};"`; exports[`Generate html document with correct lang and dir attributes. Load correct bundles. documentation with rtl and ltr langs 5`] = ` @@ -335,7 +335,7 @@ exports[`Generate html document with correct lang and dir attributes. Load corre > - + @@ -355,11 +355,11 @@ exports[`Generate html document with correct lang and dir attributes. Load corre @@ -367,22 +367,22 @@ exports[`Generate html document with correct lang and dir attributes. Load corre - @@ -396,7 +396,7 @@ exports[`Generate html document with correct lang and dir attributes. Load corre > - + @@ -413,11 +413,11 @@ exports[`Generate html document with correct lang and dir attributes. Load corre @@ -425,31 +425,31 @@ exports[`Generate html document with correct lang and dir attributes. Load corre - `; -exports[`Generate html document with correct lang and dir attributes. Load correct bundles. documentation with rtl and ltr langs 7`] = `"window.__DATA__.data.toc = {"title":"Documentation","href":"index.html","items":[{"name":"Documentation","href":"page.html","id":"Documentation-RANDOM"}],"base":"en","deepBase":1};"`; +exports[`Generate html document with correct lang and dir attributes. Load correct bundles. documentation with rtl and ltr langs 7`] = `"window.__DATA__.data.toc = {"title":"Documentation","href":"en/index.html","items":[{"name":"Documentation","href":"en/page.html","id":"Documentation-RANDOM"}]};"`; exports[`Generate html document with correct lang and dir attributes. Load correct bundles. documentation with rtl and ltr langs 8`] = ` diff --git a/tests/units/services/__snapshots__/singlePage.test.ts.snap b/tests/units/services/__snapshots__/singlePage.test.ts.snap index 3b627fe1..cd79e840 100644 --- a/tests/units/services/__snapshots__/singlePage.test.ts.snap +++ b/tests/units/services/__snapshots__/singlePage.test.ts.snap @@ -1,37 +1,37 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP exports[`Add a page prefix to anchors Should be added 1`] = ` -

-

+

`; exports[`Adding the main title Should be added the page attributes 1`] = ` -

+

Title

@@ -62,30 +62,6 @@ exports[`Decrease heading levels Should work 1`] = ` `; -exports[`Make image sources relative from the single page file External image sources should not be replaced 1`] = ` -test -`; - -exports[`Make image sources relative from the single page file Image sources should be replaced if the file is not root 1`] = ` -test -test -`; - -exports[`Make image sources relative from the single page file Image sources should not be replaced if file is root 1`] = ` -test -test -`; - exports[`Make links to pages as hashes to sections in a single page External links should not be replaced 1`] = ` + - + - + `; exports[`Make links to pages as hashes to sections in a single page Should not be replaced as hash if a link is out of the root folder 1`] = ` - + `; exports[`Make links to pages as hashes to sections in a single page Should not be replaced as hash if a link is out of the single page (but not out of the root) 1`] = ` - + `; diff --git a/tests/units/services/singlePage.test.ts b/tests/units/services/singlePage.test.ts index 5f90cdea..946c195a 100644 --- a/tests/units/services/singlePage.test.ts +++ b/tests/units/services/singlePage.test.ts @@ -7,14 +7,12 @@ import { addPagePrefixToAnchors, decreaseHeadingLevels, replaceLinks, - replaceImages, addMainTitle, } from 'utils/singlePage'; describe('Adding the main title', () => { const options = { title: 'Title', - root: __dirname, path: 'about.html', tocDir: '', }; @@ -70,7 +68,6 @@ describe('Add a page prefix to anchors', () => { const root = parse(content); addPagePrefixToAnchors(root, { - root: __dirname, path: 'index.html', tocDir: '', }); @@ -96,9 +93,8 @@ describe('Make links to pages as hashes to sections in a single page', () => { ].join('\n'); const root = parse(content); replaceLinks(root, { - root: __dirname, path: 'index.html', - tocDir: __dirname, + tocDir: '', }); expect(platformless(root.toString())).toMatchSnapshot(); }); @@ -111,9 +107,8 @@ describe('Make links to pages as hashes to sections in a single page', () => { ].join('\n'); const root = parse(content); replaceLinks(root, { - root: __dirname, path: 'folder1/index.html', - tocDir: __dirname, + tocDir: '', }); expect(platformless(root.toString())).toMatchSnapshot(); }); @@ -122,9 +117,8 @@ describe('Make links to pages as hashes to sections in a single page', () => { const content = ''; const root = parse(content); replaceLinks(root, { - root: __dirname, path: 'index.html', - tocDir: __dirname, + tocDir: '', }); expect(platformless(root.toString())).toMatchSnapshot(); }); @@ -133,9 +127,8 @@ describe('Make links to pages as hashes to sections in a single page', () => { const content = ``; const root = parse(content); replaceLinks(root, { - root: __dirname, path: 'folder/index.html', - tocDir: __dirname, + tocDir: '', }); expect(platformless(root.toString())).toMatchSnapshot(); }); @@ -144,51 +137,8 @@ describe('Make links to pages as hashes to sections in a single page', () => { const content = ``; const root = parse(content); replaceLinks(root, { - root: __dirname, path: 'service1/folder/index.html', - tocDir: join(__dirname, 'service1'), - }); - expect(platformless(root.toString())).toMatchSnapshot(); - }); -}); - -describe('Make image sources relative from the single page file', () => { - test('Image sources should not be replaced if file is root', () => { - const content = [ - `test`, - `test`, - ].join('\n'); - const root = parse(content); - replaceImages(root, { - root: __dirname, - path: 'index.html', - tocDir: __dirname, - }); - expect(platformless(root.toString())).toMatchSnapshot(); - }); - - test('Image sources should be replaced if the file is not root', () => { - const content = [ - `test`, - `test`, - ].join('\n'); - const root = parse(content); - replaceImages(root, { - root: __dirname, - path: 'folder/index.html', - tocDir: __dirname, - }); - const result = root.toString(); - expect(platformless(result)).toMatchSnapshot(); - }); - - test('External image sources should not be replaced', () => { - const content = 'test'; - const root = parse(content); - replaceImages(root, { - root: __dirname, - path: 'index.html', - tocDir: __dirname, + tocDir: 'service1', }); expect(platformless(root.toString())).toMatchSnapshot(); });