-
Notifications
You must be signed in to change notification settings - Fork 10
/
body-class.js
61 lines (49 loc) · 1.5 KB
/
body-class.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
import { getOwner } from '@ember/application';
import Service from '@ember/service';
import { A } from '@ember/array';
import { once, cancel } from '@ember/runloop';
export default class BodyClassService extends Service {
_dom = getOwner(this).lookup('service:-document');
_fastboot = getOwner(this).lookup('service:fastboot');
registrations = new Map();
register(id, classNames) {
this.registrations.set(id, classNames);
this.scheduleUpdate();
}
deregister(id) {
this.registrations.delete(id);
this.scheduleUpdate();
}
get names() {
let allNames = new Set();
for (let classNames of this.registrations.values()) {
for (let className of classNames) {
allNames.add(className);
}
}
return [...allNames];
}
scheduleUpdate() {
this.scheduledRun = once(this, this.updateBodyClass);
}
updateBodyClass() {
if (!this._dom) {
return;
}
let registeredClassNames = this.names;
let body = this._dom.body;
let attr = body.getAttribute('class');
let classList = A(attr ? attr.split(/\s+/) : []);
classList.removeObjects(this._previousNames || []);
classList.addObjects(registeredClassNames);
this._previousNames = registeredClassNames;
body.setAttribute('class', classList.join(' '));
}
willDestroy() {
if (this._fastboot && this._fastboot.isFastBoot) {
// prevent FastBoot from removing the CSS classes
// again before the response is sent out
cancel(this.scheduledRun);
}
}
}