diff --git a/aio/src/app/layout/doc-viewer/doc-viewer.component.spec.ts b/aio/src/app/layout/doc-viewer/doc-viewer.component.spec.ts index aa8d6eade0..182a8c5058 100644 --- a/aio/src/app/layout/doc-viewer/doc-viewer.component.spec.ts +++ b/aio/src/app/layout/doc-viewer/doc-viewer.component.spec.ts @@ -175,6 +175,9 @@ describe('DocViewerComponent', () => { const DOC_WITHOUT_H1 = 'Some content'; const DOC_WITH_H1 = '

Features

Some content'; const DOC_WITH_NO_TOC_H1 = '

Features

Some content'; + const DOC_WITH_EMBEDDED_TOC = '

Features

Some content'; + const DOC_WITH_EMBEDDED_TOC_WITHOUT_H1 = 'Some content'; + const DOC_WITH_EMBEDDED_TOC_WITH_NO_TOC_H1 = 'Some content'; const DOC_WITH_HIDDEN_H1_CONTENT = '

linkFeatures

Some content'; let titleService: MockTitle; let tocService: MockTocService; @@ -271,26 +274,45 @@ describe('DocViewerComponent', () => { }); describe('(ToC)', () => { - it('should add an embedded ToC element if there is an `

` heading', () => { - doPrepareTitleAndToc(DOC_WITH_H1); - const tocEl = getTocEl()!; + describe('needed', () => { + it('should add an embedded ToC element if there is an `

` heading', () => { + doPrepareTitleAndToc(DOC_WITH_H1); + const tocEl = getTocEl()!; - expect(tocEl).toBeTruthy(); - expect(tocEl.classList.contains('embedded')).toBe(true); + expect(tocEl).toBeTruthy(); + expect(tocEl.classList.contains('embedded')).toBe(true); + }); + + it('should not add a second ToC element if there a hard coded one in place', () => { + doPrepareTitleAndToc(DOC_WITH_EMBEDDED_TOC); + expect(targetEl.querySelectorAll('aio-toc').length).toEqual(1); + }); }); - it('should not add a ToC element if there is a `.no-toc` `

` heading', () => { - doPrepareTitleAndToc(DOC_WITH_NO_TOC_H1); - expect(getTocEl()).toBeFalsy(); + + describe('not needed', () => { + it('should not add a ToC element if there is a `.no-toc` `

` heading', () => { + doPrepareTitleAndToc(DOC_WITH_NO_TOC_H1); + expect(getTocEl()).toBeFalsy(); + }); + + it('should not add a ToC element if there is no `

` heading', () => { + doPrepareTitleAndToc(DOC_WITHOUT_H1); + expect(getTocEl()).toBeFalsy(); + + doPrepareTitleAndToc(EMPTY_DOC); + expect(getTocEl()).toBeFalsy(); + }); + + it('should remove ToC a hard coded one', () => { + doPrepareTitleAndToc(DOC_WITH_EMBEDDED_TOC_WITHOUT_H1); + expect(getTocEl()).toBeFalsy(); + + doPrepareTitleAndToc(DOC_WITH_EMBEDDED_TOC_WITH_NO_TOC_H1); + expect(getTocEl()).toBeFalsy(); + }); }); - it('should not add a ToC element if there is no `

` heading', () => { - doPrepareTitleAndToc(DOC_WITHOUT_H1); - expect(getTocEl()).toBeFalsy(); - - doPrepareTitleAndToc(EMPTY_DOC); - expect(getTocEl()).toBeFalsy(); - }); it('should generate ToC entries if there is an `

` heading', () => { doAddTitleAndToc(DOC_WITH_H1, 'foo'); diff --git a/aio/src/app/layout/doc-viewer/doc-viewer.component.ts b/aio/src/app/layout/doc-viewer/doc-viewer.component.ts index 7ead74d128..dce991eae3 100644 --- a/aio/src/app/layout/doc-viewer/doc-viewer.component.ts +++ b/aio/src/app/layout/doc-viewer/doc-viewer.component.ts @@ -112,10 +112,15 @@ export class DocViewerComponent implements DoCheck, OnDestroy { */ protected prepareTitleAndToc(targetElem: HTMLElement, docId: string): () => void { const titleEl = targetElem.querySelector('h1'); - const hasToc = !!titleEl && !/no-?toc/i.test(titleEl.className); + const needsToc = !!titleEl && !/no-?toc/i.test(titleEl.className); + const embeddedToc = targetElem.querySelector('aio-toc.embedded'); - if (hasToc) { + if (needsToc && !embeddedToc) { + // Add an embedded ToC if it's needed and there isn't one in the content already. titleEl!.insertAdjacentHTML('afterend', ''); + } else if (!needsToc && embeddedToc) { + // Remove the embedded Toc if it's there and not needed. + embeddedToc.remove(); } return () => { @@ -127,7 +132,7 @@ export class DocViewerComponent implements DoCheck, OnDestroy { if (titleEl) { title = (typeof titleEl.innerText === 'string') ? titleEl.innerText : titleEl.textContent; - if (hasToc) { + if (needsToc) { this.tocService.genToc(targetElem, docId); } }