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 62e3c5605c
commit 63a0582fa3
1 changed files with 7 additions and 2 deletions

View File

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