ui: Reduce mutation of html.classList (#5974)

Throughout the app we mutate the value of the root node classList on
navigation between separate pages (basically on URL change).

Every template has a unique classList for example `template-service
template-show` and `template-service template-list` etc etc.

When navigating between 2 pages, both pages using the same template yet
with different data, previoulsy we would entirely clear out the
`html.classList` and then refill it again with eaxctly the same classes.

This commit moves this to perform a diff previous to mutating the
classList, and then potentially no classList mutating is needed when
moving between 2 pages of the same template.
This commit is contained in:
John Cowen 2019-06-20 09:38:23 +01:00 committed by John Cowen
parent 74dbc71c84
commit e66a1b3874

View file

@ -11,6 +11,7 @@ export default Component.extend(SlotsMixin, {
classNameBindings: ['enabled::disabled', 'authorized::unauthorized'],
dom: service('dom'),
didReceiveAttrs: function() {
this._super(...arguments);
// right now only manually added classes are hoisted to <html>
const $root = get(this, 'dom').root();
let cls = get(this, 'class') || '';
@ -22,18 +23,22 @@ export default Component.extend(SlotsMixin, {
if (cls) {
// its possible for 'layout' templates to change after insert
// check for these specific layouts and clear them out
[...$root.classList].forEach(function(item, i) {
const receivedClasses = new Set(templatize(cls.split(' ')));
const difference = new Set([...$root.classList].filter(item => !receivedClasses.has(item)));
[...difference].forEach(function(item, i) {
if (templatize(['edit', 'show', 'list']).indexOf(item) !== -1) {
$root.classList.remove(item);
}
});
$root.classList.add(...templatize(cls.split(' ')));
$root.classList.add(...receivedClasses);
}
},
didInsertElement: function() {
this._super(...arguments);
this.didReceiveAttrs();
},
didDestroyElement: function() {
this._super(...arguments);
const cls = get(this, 'class') + ' loading';
if (cls) {
const $root = get(this, 'dom').root();