50 lines
1.7 KiB
JavaScript
50 lines
1.7 KiB
JavaScript
import Modifier from 'ember-modifier';
|
|
import { assert } from '@ember/debug';
|
|
|
|
export default class StyleModifier extends Modifier {
|
|
setStyles(newStyles = []) {
|
|
const rulesToRemove = this._oldStyles || new Set();
|
|
if (!Array.isArray(newStyles)) {
|
|
newStyles = Object.entries(newStyles);
|
|
}
|
|
newStyles.forEach(([property, value]) => {
|
|
assert(
|
|
`Your given value for property '${property}' is ${value} (${typeof value}). Accepted types are string and undefined. Please change accordingly.`,
|
|
typeof value === 'undefined' || typeof value === 'string'
|
|
);
|
|
|
|
// priority must be specified as separate argument
|
|
// value must not contain "!important"
|
|
let priority = '';
|
|
if (value.length > 0 && value.includes('!important')) {
|
|
priority = 'important';
|
|
value = value.replace('!important', '');
|
|
}
|
|
|
|
// update CSSOM
|
|
this.element.style.setProperty(property, value, priority);
|
|
|
|
// should not remove rules that have been updated in this cycle
|
|
rulesToRemove.delete(property);
|
|
});
|
|
|
|
// remove rules that were present in last cycle but aren't present in this one
|
|
rulesToRemove.forEach((rule) => this.element.style.removeProperty(rule));
|
|
|
|
// cache styles that in this rendering cycle for the next one
|
|
this._oldStyles = new Set(newStyles.map((e) => e[0]));
|
|
}
|
|
|
|
didReceiveArguments() {
|
|
if (typeof this.args.named.delay !== 'undefined') {
|
|
setTimeout((_) => {
|
|
if (typeof this !== this.args.positional[0]) {
|
|
this.setStyles(this.args.positional[0]);
|
|
}
|
|
}, this.args.named.delay);
|
|
} else {
|
|
this.setStyles(this.args.positional[0]);
|
|
}
|
|
}
|
|
}
|