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);
}
}