diff --git a/projects/ledge-render/src/lib/ledge-render.component.html b/projects/ledge-render/src/lib/ledge-render.component.html index 6fe42f34..5b9511c1 100644 --- a/projects/ledge-render/src/lib/ledge-render.component.html +++ b/projects/ledge-render/src/lib/ledge-render.component.html @@ -5,7 +5,7 @@
- +
diff --git a/projects/ledge-render/src/lib/ledge-render.component.ts b/projects/ledge-render/src/lib/ledge-render.component.ts index 43673607..304e63c0 100644 --- a/projects/ledge-render/src/lib/ledge-render.component.ts +++ b/projects/ledge-render/src/lib/ledge-render.component.ts @@ -1,9 +1,9 @@ import { ChangeDetectionStrategy, - Component, + Component, EventEmitter, Input, OnChanges, - OnInit, + OnInit, Output, SimpleChanges, } from '@angular/core'; import { Token, Tokens, TokensList } from 'marked'; @@ -26,6 +26,9 @@ export class LedgeRenderComponent implements OnInit, OnChanges { @Input() scrollToItem = 0; + @Output() + headingChange = new EventEmitter(); + markdownData: any[] = []; token = null; tokens: TokensList | any = []; @@ -34,8 +37,11 @@ export class LedgeRenderComponent implements OnInit, OnChanges { colorsForIndex = LedgeColors; isPureParagraph = true; + + lastHeading = 0; headingIndex = 0; headingMap = {}; + indexHeadingMap = {}; ngOnInit(): void { } @@ -125,9 +131,11 @@ export class LedgeRenderComponent implements OnInit, OnChanges { type: 'heading', depth: token.depth, text: inline, + headingIndex: this.headingIndex, anchor: this.slugger.slug(this.unescape(inline)), }); this.headingMap[this.headingIndex] = this.markdownData.length - 1; + this.indexHeadingMap[this.markdownData.length - 1] = this.headingIndex; this.headingIndex++; break; case 'list_start': { @@ -361,4 +369,16 @@ export class LedgeRenderComponent implements OnInit, OnChanges { stringify(str: any) { return JSON.stringify(str); } + + vsUpdate($event: any[]) { + for (const mdItem of $event) { + if (mdItem.type === 'heading') { + if (mdItem.headingIndex !== this.lastHeading) { + this.lastHeading = mdItem.headingIndex; + this.headingChange.emit(mdItem); + } + return; + } + } + } } diff --git a/src/app/features/markdown-render/markdown-render.component.html b/src/app/features/markdown-render/markdown-render.component.html index c1bdfdbd..19eaffc1 100644 --- a/src/app/features/markdown-render/markdown-render.component.html +++ b/src/app/features/markdown-render/markdown-render.component.html @@ -11,7 +11,12 @@
- + +
diff --git a/src/app/features/markdown-render/markdown-render.component.ts b/src/app/features/markdown-render/markdown-render.component.ts index 5578495e..c832d733 100644 --- a/src/app/features/markdown-render/markdown-render.component.ts +++ b/src/app/features/markdown-render/markdown-render.component.ts @@ -44,12 +44,14 @@ export class MarkdownRenderComponent sticky = false; windowScrolled = false; tocify = new Tocify(); + tocSlugger = new Slugger(); - private lastTocId: string; - private scrollItems: any[] = []; toItem = 0; private tocIndex = 0; + private lastTocId: string; + private scrollItems: any[] = []; + constructor( private markdownService: MarkdownService, private location: Location, @@ -110,7 +112,11 @@ export class MarkdownRenderComponent } const headingId = currentElement.getAttribute('id'); - const tocLink = document.getElementById('menu-' + headingId); + const menuElement = document.getElementById('menu-' + headingId); + this.scrollToMenu(menuElement, headingId); + } + + private scrollToMenu(tocLink: HTMLElement, headingId: string) { if (!!tocLink) { if (!!this.lastTocId) { const lastElement = document.getElementById('menu-' + this.lastTocId); @@ -218,4 +224,11 @@ ${link}
${childrenItems.join('')}
} }); } + + changeHeading($event: any) { + const id: string = this.tocSlugger.slug($event.anchor); + const headingId = `menu-${id}`; + const menuElement = document.getElementById(headingId); + this.scrollToMenu(menuElement, id); + } }