DEV: Refactor d-section to function correctly with loading-slider (#16216)

When using the loading-slider, the component instance is re-used across different pages and so the didInsertElement/willDestroyElement hooks are not fired during page transitions. Instead, we can lean on `didReceiveAttrs`.

Similar fix to 87b98e2862

Note that the `scrollTop` feature is still problematic under the loading slider. That will need to be addressed in a future commit.
This commit is contained in:
David Taylor 2022-03-18 11:47:23 +00:00 committed by GitHub
parent 66cf866b4a
commit 13b4b0d3c4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
1 changed files with 39 additions and 20 deletions

View File

@ -1,25 +1,19 @@
import deprecated from "discourse-common/lib/deprecated";
import Component from "@ember/component";
import { scrollTop } from "discourse/mixins/scroll-top";
import { scheduleOnce } from "@ember/runloop";
// Can add a body class from within a component, also will scroll to the top automatically.
export default Component.extend({
tagName: null,
pageClass: null,
bodyClass: null,
scrollTop: true,
export default class extends Component {
tagName = null;
pageClass = null;
bodyClass = null;
scrollTop = true;
currentClasses = new Set();
didInsertElement() {
this._super(...arguments);
if (this.pageClass) {
document.body.classList.add(`${this.pageClass}-page`);
}
if (this.bodyClass) {
document.body.classList.add(...this.bodyClass.split(" "));
}
if (this.scrollTop === "false") {
deprecated("Uses boolean instead of string for scrollTop.", {
since: "2.8.0.beta9",
@ -34,17 +28,42 @@ export default Component.extend({
}
scrollTop();
},
}
didReceiveAttrs() {
this._super(...arguments);
scheduleOnce("afterRender", this, this._updateClasses);
}
willDestroyElement() {
this._super(...arguments);
scheduleOnce("afterRender", this, this._removeClasses);
}
_updateClasses() {
if (this.isDestroying || this.isDestroyed) {
return;
}
const desiredClasses = new Set();
if (this.pageClass) {
document.body.classList.remove(`${this.pageClass}-page`);
desiredClasses.add(`${this.pageClass}-page`);
}
if (this.bodyClass) {
for (const bodyClass of this.bodyClass.split(" ")) {
desiredClasses.add(bodyClass);
}
}
if (this.bodyClass) {
document.body.classList.remove(...this.bodyClass.split(" "));
}
},
});
document.body.classList.add(...desiredClasses);
const removeClasses = [...this.currentClasses].filter(
(c) => !desiredClasses.has(c)
);
document.body.classList.remove(...removeClasses);
this.currentClasses = desiredClasses;
}
_removeClasses() {
document.body.classList.remove(...this.currentClasses);
}
}