diff --git a/javascripts/discourse/components/table-of-contents.js b/javascripts/discourse/components/table-of-contents.js index b9401b7..a99777e 100644 --- a/javascripts/discourse/components/table-of-contents.js +++ b/javascripts/discourse/components/table-of-contents.js @@ -1,8 +1,11 @@ import Component from "@glimmer/component"; import { action } from "@ember/object"; import { headerOffset } from "discourse/lib/offset-calculator"; +import { inject as service } from "@ember/service"; export default class TableOfContents extends Component { + @service("tableOfContentsData") data; + @action scrollToBottom(e) { e.preventDefault(); diff --git a/javascripts/discourse/initializers/disco-toc-main.js b/javascripts/discourse/initializers/disco-toc-main.js index 04aa282..fd296c5 100644 --- a/javascripts/discourse/initializers/disco-toc-main.js +++ b/javascripts/discourse/initializers/disco-toc-main.js @@ -1,6 +1,5 @@ import domUtils from "discourse-common/utils/dom-utils"; import { headerOffset } from "discourse/lib/offset-calculator"; -import { later } from "@ember/runloop"; import { slugify } from "discourse/lib/utilities"; import { withPluginApi } from "discourse/lib/plugin-api"; import { bind } from "discourse-common/utils/decorators"; @@ -10,6 +9,8 @@ export default { initialize() { withPluginApi("1.0.0", (api) => { + this.tocService = api.container.lookup("service:table-of-contents-data"); + api.decorateCookedElement(this.decorate, { id: "disco-toc", onlyStream: true, @@ -89,20 +90,8 @@ export default { el.classList.add("d-toc-cooked"); - if (document.querySelector(".d-toc-wrapper")) { - this.buildTOC(Array.from(headings)); - document.addEventListener("click", this.clickTOC, false); - } else { - // try again if decoration happens while outlet is not rendered - // this is due to core resetting `canRender` for topic-navigation - // when transitioning between topics - later(() => { - if (document.querySelector(".d-toc-wrapper")) { - this.buildTOC(Array.from(headings)); - document.addEventListener("click", this.clickTOC, false); - } - }, 300); - } + this.buildTOC(Array.from(headings)); + document.addEventListener("click", this.clickTOC, false); }, updateTOCSidebar() { @@ -191,10 +180,10 @@ export default { }, buildTOC(headings) { - const toc = document.querySelector("#d-toc"); const primaryH = headings[0].tagName; const primaryHeadings = headings.filter((n) => n.tagName === primaryH); let nextIndex = headings.length; + let result = ""; primaryHeadings.forEach((primaryHeading, index) => { const ul = document.createElement("ul"); @@ -224,10 +213,10 @@ export default { } }); - toc.appendChild(ul); + result += ul.outerHTML; }); - return toc; + this.tocService.html = result; }, buildItem(node) { diff --git a/javascripts/discourse/services/table-of-contents-data.js b/javascripts/discourse/services/table-of-contents-data.js new file mode 100644 index 0000000..93d11c9 --- /dev/null +++ b/javascripts/discourse/services/table-of-contents-data.js @@ -0,0 +1,6 @@ +import Service from "@ember/service"; +import { tracked } from "@glimmer/tracking"; + +export default class TableOfContentsData extends Service { + @tracked html = ""; +} diff --git a/javascripts/discourse/templates/components/table-of-contents.hbs b/javascripts/discourse/templates/components/table-of-contents.hbs index c938ccb..88e96e4 100644 --- a/javascripts/discourse/templates/components/table-of-contents.hbs +++ b/javascripts/discourse/templates/components/table-of-contents.hbs @@ -14,5 +14,6 @@