Skip to main content
Go to Latest
File
import Prefixer from "./prefixer.js";import Browsers from "./browsers.js";import * as utils from "./utils.js";
class Declaration extends Prefixer { /** * Always true, because we already get prefixer by property name */ check(/* decl */) { return true; }
/** * Return prefixed version of property */ prefixed(prop, prefix) { return prefix + prop; }
/** * Return unprefixed version of property */ normalize(prop) { return prop; }
/** * Check `value`, that it contain other prefixes, rather than `prefix` */ otherPrefixes(value, prefix) { for (let other of Browsers.prefixes()) { if (other === prefix) { continue; } if (value.includes(other)) { return true; } } return false; }
/** * Set prefix to declaration */ set(decl, prefix) { decl.prop = this.prefixed(decl.prop, prefix); return decl; }
/** * Should we use visual cascade for prefixes */ needCascade(decl) { if (!decl._autoprefixerCascade) { decl._autoprefixerCascade = this.all.options.cascade !== false && decl.raw("before").includes("\n"); } return decl._autoprefixerCascade; }
/** * Return maximum length of possible prefixed property */ maxPrefixed(prefixes, decl) { if (decl._autoprefixerMax) { return decl._autoprefixerMax; }
let max = 0; for (let prefix of prefixes) { prefix = utils.removeNote(prefix); if (prefix.length > max) { max = prefix.length; } } decl._autoprefixerMax = max;
return decl._autoprefixerMax; }
/** * Calculate indentation to create visual cascade */ calcBefore(prefixes, decl, prefix = "") { let max = this.maxPrefixed(prefixes, decl); let diff = max - utils.removeNote(prefix).length;
let before = decl.raw("before"); if (diff > 0) { before += Array(diff).fill(" ").join(""); }
return before; }
/** * Remove visual cascade */ restoreBefore(decl) { let lines = decl.raw("before").split("\n"); let min = lines[lines.length - 1];
this.all.group(decl).up((prefixed) => { let array = prefixed.raw("before").split("\n"); let last = array[array.length - 1]; if (last.length < min.length) { min = last; } });
lines[lines.length - 1] = min; decl.raws.before = lines.join("\n"); }
/** * Clone and insert new declaration */ insert(decl, prefix, prefixes) { let cloned = this.set(this.clone(decl), prefix); if (!cloned) return undefined;
let already = decl.parent.some( (i) => i.prop === cloned.prop && i.value === cloned.value, ); if (already) { return undefined; }
if (this.needCascade(decl)) { cloned.raws.before = this.calcBefore(prefixes, decl, prefix); } return decl.parent.insertBefore(decl, cloned); }
/** * Did this declaration has this prefix above */ isAlready(decl, prefixed) { let already = this.all.group(decl).up((i) => i.prop === prefixed); if (!already) { already = this.all.group(decl).down((i) => i.prop === prefixed); } return already; }
/** * Clone and add prefixes for declaration */ add(decl, prefix, prefixes, result) { let prefixed = this.prefixed(decl.prop, prefix); if ( this.isAlready(decl, prefixed) || this.otherPrefixes(decl.value, prefix) ) { return undefined; } return this.insert(decl, prefix, prefixes, result); }
/** * Add spaces for visual cascade */ process(decl, result) { if (!this.needCascade(decl)) { super.process(decl, result); return; }
let prefixes = super.process(decl, result);
if (!prefixes || !prefixes.length) { return; }
this.restoreBefore(decl); decl.raws.before = this.calcBefore(prefixes, decl); }
/** * Return list of prefixed properties to clean old prefixes */ old(prop, prefix) { return [this.prefixed(prop, prefix)]; }}
export default Declaration;