@amaui/style
Version:
CSS in JS styling solution
801 lines (626 loc) • 30.7 kB
JavaScript
import _defineProperty from "@babel/runtime/helpers/defineProperty";
import hash from '@amaui/utils/hash';
import Try from '@amaui/utils/try';
import castParam from '@amaui/utils/castParam';
import getEnvironment from '@amaui/utils/getEnvironment';
import merge from '@amaui/utils/merge';
import AmauiStyle from './AmauiStyle';
import AmauiStyleSheet from './AmauiStyleSheet';
import AmauiStyleRuleProperty from './AmauiStyleRuleProperty';
import classNamesMethod from './classNames';
import { cammelCaseToKebabCase, getID, getRefs, is, isAmauiSubscription, valueResolve } from './utils';
const optionsDefault = {
mode: 'regular',
value_version: 'value',
version: 'property',
pure: false,
index: 0,
sort: true,
prefix: true,
rtl: true
};
const env = getEnvironment();
class AmauiStyleRule {
constructor(value, property) {
var _this = this;
let options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : optionsDefault;
_defineProperty(this, "value_version", 'value');
_defineProperty(this, "mode", 'regular');
_defineProperty(this, "version", 'property');
_defineProperty(this, "pure", false);
_defineProperty(this, "index", 0);
_defineProperty(this, "parents", []);
_defineProperty(this, "status", 'idle');
_defineProperty(this, "isVariable", false);
_defineProperty(this, "static", true);
_defineProperty(this, "rules_owned", []);
_defineProperty(this, "className_", '');
_defineProperty(this, "selector_", '');
_defineProperty(this, "classNames_", '');
_defineProperty(this, "keyframesName_", '');
_defineProperty(this, "values", {
value: undefined,
css: ''
});
_defineProperty(this, "rules", []);
_defineProperty(this, "makeRuleClassNameDefault", function () {
var _this$amauiStyle$opti;
let value = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 'a';
return "".concat(((_this$amauiStyle$opti = _this.amauiStyle.options) === null || _this$amauiStyle$opti === void 0 ? void 0 : _this$amauiStyle$opti.classNamePrefix) || '').concat(value, "-").concat(++_this.counter.className);
});
_defineProperty(this, "makeRuleKeyframesNameDefault", function () {
var _this$amauiStyle$opti2;
let value = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 'a';
return "".concat(((_this$amauiStyle$opti2 = _this.amauiStyle.options) === null || _this$amauiStyle$opti2 === void 0 ? void 0 : _this$amauiStyle$opti2.classNamePrefix) || '').concat(value, "-").concat(++_this.counter.keyframesName);
});
this.value = value;
this.property = property;
this.options = options;
this.options = { ...optionsDefault,
...this.options
};
this.init();
}
get selector() {
return this.selector_;
}
set selector(value) {
this.selector_ = value;
}
get className() {
return this.className_;
}
set className(value) {
const parentKeyframes = this.parent.version === 'at-rule';
if (!parentKeyframes) {
this.className_ = value; // Update classNames
if (!this.classNames.match(new RegExp("^(.)?".concat(this.className, " | (.)?").concat(this.className, " | (.)?").concat(this.className, "$"), 'g'))) this.classNames = "".concat(this.className, " ").concat(this.classNames).trim();
this.amauiStyleSheet.names.classNames[this.property] = this.className; // in amauiStyleSheetManager only for static sheets
if (this.amauiStyleSheet.version === 'static' && this.amauiStyleSheet.amauiStyleSheetManager) {
this.amauiStyleSheet.amauiStyleSheetManager.names.classNames[this.property] = this.className;
}
}
}
get classNames() {
return this.classNames_;
}
set classNames(value) {
this.classNames_ = value;
this.amauiStyleSheet.names.classes[this.property] = this.classNames; // in amauiStyleSheetManager only for static sheets
if (this.amauiStyleSheet.version === 'static' && this.amauiStyleSheet.amauiStyleSheetManager) {
this.amauiStyleSheet.amauiStyleSheetManager.names.classes[this.property] = this.classNames;
}
}
get keyframesName() {
return this.keyframesName_;
}
set keyframesName(value) {
this.keyframesName_ = value;
const property = this.property.indexOf('@') === 0 ? this.property.split(' ')[1] : this.property; // Update amauiStyleSheet keyframes
this.amauiStyleSheet.names.keyframes[property] = this.keyframesName; // in amauiStyleSheetManager only for static sheets
if (this.amauiStyleSheet.version === 'static' && this.amauiStyleSheet.amauiStyleSheetManager) {
if (!this.amauiStyleSheet.amauiStyleSheetManager.names.keyframes[property]) {
this.amauiStyleSheet.amauiStyleSheetManager.names.keyframes[property] = this.keyframesName;
}
}
}
get hash() {
return this.hash_;
}
get parent() {
return this.parents[this.parents.length - 1];
}
get response() {
return {
css: this.values.css
};
}
get css() {
return this.response.css;
}
get allOwnedCss() {
let value = this.values.css;
this.rules_owned.filter(item => item instanceof AmauiStyleRule).forEach(item => value += "\n\n".concat(item.allOwnedCss)); // Replace its own property selector with a constant
value = value.replace("".concat(this.selector || this.property, " {"), 'AMAUI_ITEM {');
return value;
}
get counter() {
return AmauiStyle.counter;
}
updateValues() {
let hash_ = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : true;
// Response
const selector = this.selector || this.property;
this.values.css = "".concat(selector, " {\n");
let empty = true;
this.rules.forEach((rule, index) => {
const css = rule.value.css;
if (css) {
empty = false;
this.values.css += "".concat(' '.repeat(rule.value.level_actual)).concat(css).concat('\n'.repeat(rule.value instanceof AmauiStyleRule && index !== this.rules.length - 1 ? 2 : 1));
}
});
this.values.css += "".concat(' '.repeat(this.level_actual), "}"); // Empty
// Only if it's a variable,
// in some use cases if there are no props in css,
// we still have to insertRule for dynamic rules
// so we have a rule ref for that amauiStyleRuleProperty to
// update with a new value on update
if (empty && (!this.className || this.amauiStyleSheet.version === 'static')) this.values.css = ''; // Hash
if (hash_) this.makeHash();
}
makeHash() {
if (!this.hash && this.static && this.amauiStyleSheet.amauiStyle.options.optimize && this.amauiStyleSheet.version === 'static' && this.version === 'property' && !(this.isVariable && this.amauiStyleSheet.mode === 'atomic')) this.hash_ = hash(this.amauiStyleSheet.mode === 'atomic' ? this.css : this.allOwnedCss);
}
init(value_) {
var _this$property,
_this2 = this;
let value = value_ !== undefined ? value_ : this.value; // Options
this.mode = this.options.mode || 'regular';
this.version = this.options.version || 'property';
this.pure = this.options.pure !== undefined ? this.options.pure : this.pure;
this.index = this.options.index !== undefined ? this.options.index : this.index;
this.owner = this.options.owner;
this.parents = this.options.parents || [];
this.amauiStyleSheet = this.options.amauiStyleSheet;
this.amauiStyle = this.options.amauiStyle;
if (this.id === undefined) this.id = getID();
if (this.level === undefined) this.level = this.parents.length - 1;
if (this.owner) this.level_actual = this.owner.level_actual === undefined ? 0 : this.owner.level_actual + 1; // Add to rules_owned to all parents
this.parents.filter(parent => !(parent instanceof AmauiStyleSheet)).forEach(parent => parent.rules_owned.push(this)); // Make string template value into an object
const valueString = () => {
const rule = {};
value.trim().split('\n').filter(Boolean).map(item => item.trim()).forEach(item => {
if (item) {
const items = item.split(':');
let value__ = items[1];
const property = items[0];
value__ = value__ && value__.trim().replace(';', '');
if (property && value__) rule[property] = castParam(value__, {
decode: false
});
}
});
return rule;
};
if (is('string', value)) value = valueString();
if (is('object', value)) {
if (value['@pure'] !== undefined) this.pure = !!value['@pure'];
if (value['@p'] !== undefined) this.pure = !!value['@p'];
}
if (!this.pure && this.level === 0 && this.property.indexOf('@') !== 0) this.isVariable = true; // value method or amauiSubscription
if (is('function', value)) this.value_version = 'method';else if (isAmauiSubscription(value)) {
this.value_version = 'amaui_subscription';
if (!value.subscribed) value.subscribed = [];
if (value.subscribed.indexOf(this) === -1) {
value.subscribe(this.update.bind(this));
value.subscribed.push(this);
}
} else {
this.values.value = value;
}
const atRule = ((_this$property = this.property) === null || _this$property === void 0 ? void 0 : _this$property.indexOf('@')) === 0;
this.version = atRule ? 'at-rule' : 'property'; // method or AmauiSubscription
if (['method', 'amaui_subscription'].indexOf(this.value_version) > -1) {
if (this.value_version === 'method') this.values.value = Try(() => value(this.amauiStyleSheet.props));else if (this.value_version === 'amaui_subscription') this.values.value = this.value.value; // Value
this.values.value = is('function', this.values.value) ? Try(() => this.values.value(this.amauiStyleSheet.props)) : this.values.value;
}
value = this.values.value;
if (is('object', value)) {
// Additional @classNames provided
if (value['@classNames'] || value['@cs']) {
const classNames = classNamesMethod(value['@classNames'] || value['@cs']);
if (!this.classNames.match(new RegExp("^".concat(classNames, " | ").concat(classNames, " | ").concat(classNames, "$"), 'g'))) this.classNames = "".concat(this.classNames || '', " ").concat(classNames).trim();
} // Options
if (value['@options'] || value['@o']) this.options = merge(value['@options'] || value['@o'] || {}, this.options);
const props = Object.keys(value); // rules owned
const rules_owned = this.rules_owned; // Reset rules and rules owned
this.rules = [];
this.rules_owned = []; // Add all new rules
// and it adds new and existing again
props.forEach(prop => this.addProperty(prop, value[prop], this.rules.length, false, false)); // Remove all the previous rules
rules_owned.forEach(rule => rule.remove()); // Sort and making unique rules
this.unique; // Dynamic
const dynamic = function () {
let rule = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : _this2;
return rule.rules.some(item => is('function', item.value.value) || isAmauiSubscription(item.value.value) || item.value instanceof AmauiStyleRule && dynamic(item.value));
}; // Static
this.static = !dynamic();
} // Add itself to owner rules
if (this.owner) {
const exists = this.owner.rules.find(rule => rule.value.id === this.id);
if (!exists) this.owner.rules.push({
property: this.property,
value: this
});
} // With this we have allOwnedCss
// available for hash value
this.updateValues(); // Status
this.status = 'inited';
}
addProperty(prop, value) {
var _parent$property;
let index = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : this.rules.length;
let unique = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : true;
let add = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : true;
const atRule_ = prop.indexOf('@') === 0;
const parent = this;
const parentAtRule = this.version === 'at-rule';
const parentKeyFrames = parentAtRule && ((_parent$property = parent.property) === null || _parent$property === void 0 ? void 0 : _parent$property.indexOf('@keyframes')) > -1;
const selector = prop.indexOf('&') > -1 || parentAtRule || parentKeyFrames;
const isProperty = !(atRule_ || selector) || ['@font-face'].includes(parent.property);
const toSkip = ['@classNames', '@cs', '@options', '@o', '@pure', '@p'].indexOf(prop) > -1;
if (toSkip) return; // if it's a css property
if (isProperty) {
const property = cammelCaseToKebabCase(prop);
const {
value: ruleValues = [],
options
} = valueResolve(property, value, this.amauiStyle); // Add to rules
ruleValues.forEach(item => {
if (this.amauiStyleSheet.mode === 'regular' || !parent.isVariable) {
if (!!item) {
AmauiStyleRuleProperty.make(item, property, {
value_version: is('function', item) || isAmauiSubscription(item) ? is('function', item) ? 'method' : 'amaui_subscription' : 'value',
pure: this.pure,
owner: parent,
parents: [...parent.parents, parent],
amauiStyleRule: parent,
amauiStyleSheet: parent.amauiStyleSheet,
amauiStyle: parent.amauiStyle,
...options.rule
});
}
} else if (this.amauiStyleSheet.mode === 'atomic' && parent.isVariable) {
AmauiStyleRule.make({
[property]: item
}, env.amaui_methods.makeName.next().value, {
mode: 'atomic',
version: 'property',
pure: this.pure,
index: this.index + 1 + index,
owner: parent.parent,
parents: [...parent.parents, parent],
amauiStyleSheet: parent.amauiStyleSheet,
amauiStyle: parent.amauiStyle
});
}
});
} else {
// Pre
this.amauiStyle.subscriptions.rule.pre.emit();
let rule;
const parents = [...parent.parents, parent]; // if its an at-rule
const atTopLevel = ['@import', '@charset', '@namespace', '@color-profile', '@property', '@font-feature-values', '@counter-style', '@keyframes', '@font-face', '@page'];
const atNested = ['@media', '@supports']; // if parent is keyframes
if (parentKeyFrames) {
rule = AmauiStyleRule.make(value, prop, {
mode: 'regular',
version: atRule_ ? 'at-rule' : 'property',
pure: false,
index,
owner: parent,
parents,
amauiStyleSheet: parent.amauiStyleSheet,
amauiStyle: parent.amauiStyle
});
} // if it's a top level at-rule
else if (atRule_ && atTopLevel.some(item => prop.indexOf(item) === 0)) {
rule = AmauiStyleRule.make(value, prop, {
mode: 'regular',
version: atRule_ ? 'at-rule' : 'property',
pure: false,
index,
owner: this.amauiStyleSheet,
parents,
amauiStyleSheet: parent.amauiStyleSheet,
amauiStyle: parent.amauiStyle
});
} // if it's @media or @supports or
// it's & or a $ ref value
else if (atRule_ && atNested.some(item => prop.indexOf(item) === 0) || selector) {
let owner;
for (let i = parents.length - 1; i >= 0; i--) {
owner = parents[i]; // Move it to nearest @media or @supports or AmauiStyleSheet parent as a rule in rules value
// only if the parent is at-rule @media or @supports, or AmauiStyleSheet
if (owner.version === 'at-rule' && atNested.some(item => owner.property.indexOf(item) === 0) || owner instanceof AmauiStyleSheet) break;
}
rule = AmauiStyleRule.make(value, prop, {
mode: 'regular',
version: atRule_ ? 'at-rule' : 'property',
pure: false,
index,
owner,
parents,
amauiStyleSheet: parent.amauiStyleSheet,
amauiStyle: parent.amauiStyle
});
} // Post
this.amauiStyle.subscriptions.rule.post.emit(rule);
} // Adding individual new prop
// Sort and making unique rules
if (unique) this.unique;
if (add) {
// Add
const added = this.add(); // Update
if (!added) this.rules_owned.forEach(rule => rule.update());
}
}
add() {
let update = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : true;
// Update values
// manually adding the rule
if (!this.css) this.updateValues(); // Make selector
this.makeSelector(); // add for amauiStyleRule value
this.rules_owned.filter(rule => rule instanceof AmauiStyleRule).forEach(rule => rule.add()); // Update values
if (update) this.updateValues(); // Add rule if sheet is active
if (this.amauiStyleSheet.status === 'active') return this.addRuleToCss();
this.status = 'active';
}
updateProps() {
if (['method', 'amaui_subscription'].indexOf(this.value_version) > -1) this.init(); // Add
this.add(false); // Update
this.rules_owned.forEach(rule => rule.update()); // Update values
this.updateValues();
this.amauiStyle.subscriptions.rule.update_props.emit(this);
}
update(value) {
// Manual update
if (value !== undefined || ['method', 'amaui_subscription'].indexOf(this.value_version) > -1) this.init(value); // Add
this.add(false); // Update
this.rules_owned.forEach(rule => rule.update()); // Update values
this.updateValues();
this.amauiStyle.subscriptions.rule.update.emit(this);
}
remove() {
// Remove all own amauiStyleRules
this.rules_owned.filter(rule => rule instanceof AmauiStyleRule).forEach(rule => rule.remove()); // Only if rule and amauiStyleSheet.sheet exists
// find index of the rule in the sheet
// remove the rule from the sheet
const ref = this.amauiStyle.refs[this.hash]; // No ref or ref is main and ref.refs are empty
if (!ref || ref.main.rule === this && !ref.refs.length) {
if (ref) delete this.amauiStyle.refs[this.hash];
if (this.amauiStyleSheet.sheet) {
const index = Array.from(this.amauiStyleSheet.sheet.cssRules).findIndex(item => item === this.rule);
if (index > -1) this.amauiStyleSheet.sheet.deleteRule(index);
}
this.clear();
} else if (ref && ref.main.rule !== this) {
const indexRef = ref.refs.indexOf(this.amauiStyleSheet);
if (indexRef > -1) ref.refs.splice(indexRef, 1); // if ref is removed and there are no more refs trigger sheet remove
// which if that sheet has no more refs will be removed
if (!ref.refs.length && ref.main.sheet.status === 'remove') ref.main.sheet.remove();
this.clear();
}
}
addRuleToCss() {
// if !rule ref &
// if not a ref rule
if (!this.rule && !this.ref) {
const css = this.css;
if (css) {
const rule = this.owner.sheet || this.owner.rule;
if (rule !== null && rule !== void 0 && rule.cssRules) {
let index = rule.cssRules.length;
index = Try(() => rule.insertRule(css, index));
if (index !== undefined) {
const ruleCSS = rule.cssRules[index];
this.rule = ruleCSS;
this.amauiStyle.subscriptions.rule.add.emit(this);
return true;
}
}
}
}
}
addRuleRef() {
if (!this.rule) {
const rule = this.owner.sheet || this.owner.rule;
if (rule !== null && rule !== void 0 && rule.cssRules) {
const ref = Array.from(rule.cssRules).find(item => item.selectorText === this.selector);
if (ref !== undefined) this.rule = ref; // Move through rules
this.rules_owned.filter(rule_ => rule_ instanceof AmauiStyleRule).forEach(rule_ => rule_.addRuleRef());
}
}
}
makeSelector() {
if (!this.selector) {
// Make hash first so we can use refs
if (!this.hash) this.makeHash();
const parentAtRule = this.parent.version === 'at-rule';
const isKeyframes = this.property.indexOf('@keyframes') === 0; // Variable
if (this.isVariable || this.mode === 'atomic' || isKeyframes) {
// if it's a variable
this.makeRuleClassName(); // if it's a keyframes rule
this.makeRuleKeyframesName();
} else {
// Make property the selector
this.selector = this.property; // level 0 property inside an at-rule
if (parentAtRule && this.version === 'property') {
// & ref
let parent = this.parent;
while (parent.version === 'at-rule') parent = parent.parent;
this.selector = this.selector.replace(/&/g, parent.selector); // properties ie. body should remain the same targeting html element
// we only replace $ ref values in properties
// $ ref
const refs = getRefs(this.property);
refs.forEach(ref => {
const className = this.makeClassName(ref);
const regex = new RegExp("\\$".concat(ref), 'g');
this.selector = this.property.replace(regex, ".".concat(className));
});
} // other regular selectors
// and & value rules
else {
// & ref
this.selector = this.selector.replace(/&/g, this.parent.selector); // $ ref
const refs = getRefs(this.selector);
refs.forEach(ref => {
const className = this.makeClassName(ref);
const regex = new RegExp("\\$".concat(ref), 'g');
this.selector = this.selector.replace(regex, ".".concat(className));
});
}
} // Move through the rules
this.rules.forEach(rule => rule.value.makeSelector()); // Update values without hash
this.updateValues(false);
}
}
makeClassName(property, rule) {
var _this$amauiStyleSheet, _this$amauiStyle$subs;
const names = ((_this$amauiStyleSheet = this.amauiStyleSheet.amauiStyleSheetManager) === null || _this$amauiStyleSheet === void 0 ? void 0 : _this$amauiStyleSheet.names) || this.amauiStyleSheet.names;
const cached = names.classNames[property];
if (cached) return cached; // amauiStyle ref
// ref className already exists for the same hash
const ref = this.amauiStyle.refs[this.hash]; // Only reuse classNames for static amauiStyleSheets and for variables only not & rules
if (rule instanceof AmauiStyleRule && (rule.isVariable || rule.mode === 'atomic') && this.hash && ref && this.amauiStyleSheet.version === 'static') {
// Push amauiStyleSheet ref if it doesn't already exist in refs
if (ref.main.sheet !== this.amauiStyleSheet && ref.refs.indexOf(this.amauiStyleSheet) === -1) ref.refs.push(this.amauiStyleSheet); // Update rule ref
rule.ref = ref;
return ref.className;
} // Make a className
const className = // Make with plugin/s
((_this$amauiStyle$subs = this.amauiStyle.subscriptions.className.name.map({
property,
value: rule === null || rule === void 0 ? void 0 : rule.value
})) === null || _this$amauiStyle$subs === void 0 ? void 0 : _this$amauiStyle$subs.value) || // Make with a default method
this.makeRuleClassNameDefault(property); // Add to amauiStyle ref,
// only reuse classNames for static amauiStyleSheets
if (rule instanceof AmauiStyleRule && (rule.isVariable || rule.mode === 'atomic') && this.hash && this.amauiStyleSheet.version === 'static') {
this.amauiStyle.refs[this.hash] = {
main: {
sheet: this.amauiStyleSheet,
rule: this
},
className,
refs: []
};
} // if no rule, means it's a non-existent (or dynamic) variable
// so cache the className value as this value
if (!rule) {
this.amauiStyleSheet.names.classNames[property] = className;
this.amauiStyleSheet.names.classes[property] = className;
if (this.amauiStyleSheet.version === 'static' && this.amauiStyleSheet.amauiStyleSheetManager) {
this.amauiStyleSheet.amauiStyleSheetManager.names.classNames[property] = className;
this.amauiStyleSheet.amauiStyleSheetManager.names.classes[property] = className;
}
}
return className;
}
makeRuleClassName() {
let property = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : this.property;
let rule = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : this;
if (rule instanceof AmauiStyleRule && (rule.isVariable || rule.mode === 'atomic') && !rule.className) {
var _this$amauiStyleSheet2;
const names = ((_this$amauiStyleSheet2 = this.amauiStyleSheet.amauiStyleSheetManager) === null || _this$amauiStyleSheet2 === void 0 ? void 0 : _this$amauiStyleSheet2.names) || this.amauiStyleSheet.names;
const cached = names.classNames[rule.property];
if (cached && rule.className) return cached; // Make a className
// Pre
this.amauiStyle.subscriptions.className.pre.emit(); // Name
const className = this.makeClassName(property, rule); // Post
this.amauiStyle.subscriptions.className.post.emit(className);
rule.className = className;
rule.selector = ".".concat(className);
return className;
}
}
makeRuleKeyframesName() {
let property_ = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : this.property;
let rule = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : this;
if (rule instanceof AmauiStyleRule && !rule.keyframesName && rule.property.indexOf('@keyframes') === 0) {
var _this$amauiStyleSheet3, _this$amauiStyle$subs2;
const keyframe = property_.indexOf('@keyframes') === 0;
const property = keyframe ? property_.split(' ')[1] : property_;
const names = ((_this$amauiStyleSheet3 = this.amauiStyleSheet.amauiStyleSheetManager) === null || _this$amauiStyleSheet3 === void 0 ? void 0 : _this$amauiStyleSheet3.names) || this.amauiStyleSheet.names;
const cached = names.keyframes[property];
if (cached) return cached; // Make a keyframes name value
// Pre
this.amauiStyle.subscriptions.keyframes.pre.emit(); // Name
const keyframesName = // Make with plugin/s
((_this$amauiStyle$subs2 = this.amauiStyle.subscriptions.keyframes.name.map({
property,
value: rule.value
})) === null || _this$amauiStyle$subs2 === void 0 ? void 0 : _this$amauiStyle$subs2.value) || // Make with a default method
this.makeRuleKeyframesNameDefault(property); // Post
this.amauiStyle.subscriptions.keyframes.post.emit(keyframesName);
rule.keyframesName = keyframesName; // Add to selector as well
rule.selector = "@keyframes ".concat(keyframesName);
}
}
get rule() {
return this.rule_;
}
set rule(rule) {
var _this$rule, _this$rule$cssRules;
// Update active status
this.status = 'active';
this.rule_ = rule;
if (!!((_this$rule = this.rule) !== null && _this$rule !== void 0 && (_this$rule$cssRules = _this$rule.cssRules) !== null && _this$rule$cssRules !== void 0 && _this$rule$cssRules.length)) {
Array.from(this.rule.cssRules).forEach(item => {
let selector = item.selectorText;
if (item instanceof CSSMediaRule) selector = "@media ".concat(item.conditionText);else if (item instanceof CSSSupportsRule) selector = "@supports ".concat(item.conditionText);
const rule_ = this.rules.find(rule__ => rule__.value.selector === selector);
if (rule_) rule_.value.rule = item;
});
}
}
get unique() {
var _this$amauiStyleSheet4, _this$amauiStyleSheet5;
// Remove duplicate rules
const values = [];
this.rules.forEach((rule, index) => {
const exists = rule instanceof AmauiStyleRuleProperty && values.find(item => item instanceof AmauiStyleRuleProperty && item.values.property === rule.values.property && item.values.value === rule.values.value);
if (exists) this.rules.splice(index, 1);else values.push(rule);
}); // Native sort based on levels first
// for making, updating & refs
this.rules.sort((a, b) => {
if (a.value.level === b.value.level) return 0;
return a.value.level < b.value.level ? -1 : 1;
});
const atRule = this.version === 'at-rule'; // Sort
const useSort = !atRule && this.amauiStyle.options.rule.sort && (this.amauiStyleSheet !== undefined || this.amauiStyleSheet.options.rule.sort !== false) && (((_this$amauiStyleSheet4 = this.amauiStyleSheet) === null || _this$amauiStyleSheet4 === void 0 ? void 0 : _this$amauiStyleSheet4.amauiTheme) !== undefined || ((_this$amauiStyleSheet5 = this.amauiStyleSheet.amauiTheme) === null || _this$amauiStyleSheet5 === void 0 ? void 0 : _this$amauiStyleSheet5.options.rule.sort) !== false) && // by default is true
this.options.sort !== false;
if (useSort) {
this.amauiStyle.subscriptions.rules.sort.map(this.rules); // Post
this.amauiStyle.subscriptions.rules.sort.emit(this);
}
return this.rules;
}
clear() {
this.rule = undefined;
this.ref = undefined;
this.status = 'idle'; // rules
if (this.owner) {
const index = this.owner.rules.findIndex(item => item.value === this);
if (index > -1) this.owner.rules.splice(index, 1);
} // rules owned
this.parents.filter(parent => !(parent instanceof AmauiStyleSheet)).forEach(parent => {
const index = parent.rules_owned.findIndex(item => item.value === this);
if (index > -1) parent.rules_owned.splice(index, 1);
}); // remove it's selector
// or keyframes name from
// sheet and sheetManager
if (this.className) {
delete this.amauiStyleSheet.names.classNames[this.property];
delete this.amauiStyleSheet.names.classes[this.property];
delete this.amauiStyleSheet.amauiStyleSheetManager.names.classNames[this.property];
delete this.amauiStyleSheet.amauiStyleSheetManager.names.classes[this.property];
} else if (this.keyframesName) {
const property = this.property.split(' ')[1];
delete this.amauiStyleSheet.names.keyframes[property];
delete this.amauiStyleSheet.amauiStyleSheetManager.names.keyframes[property];
}
this.amauiStyle.subscriptions.rule.remove.emit(this);
}
static make(value, property) {
let options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {
mode: 'regular',
version: 'property',
pure: false,
index: 0,
parents: [this]
};
return new AmauiStyleRule(value, property, options);
}
}
export default AmauiStyleRule;