'use strict'; var removeRule = require('./vcssom/removeRule').removeRule; exports.addon = function (renderer) { // VCSSOM support only browser environment. if (!renderer.client) return; if (process.env.NODE_ENV !== 'production') { require('./__dev__/warnOnMissingDependencies')('cssom', renderer, ['createRule']); // cssom } var kebab = renderer.kebab; function VRule (selector, prelude) { this.rule = renderer.createRule(selector, prelude); this.decl = {}; } VRule.prototype.diff = function (newDecl) { var oldDecl = this.decl; var style = this.rule.style; var property; for (property in oldDecl) if (newDecl[property] === undefined) style.removeProperty(property); for (property in newDecl) if (newDecl[property] !== oldDecl[property]) style.setProperty(kebab(property), newDecl[property]); this.decl = newDecl; }; VRule.prototype.del = function () { removeRule(this.rule); }; function VSheet () { /** * { * '': { * '': { * color: 'red * } * } * } */ this.tree = {}; } VSheet.prototype.diff = function (newTree) { var oldTree = this.tree; // Remove media queries not present in new tree. for (var prelude in oldTree) { if (newTree[prelude] === undefined) { var rules = oldTree[prelude]; for (var selector in rules) rules[selector].del(); } } for (var prelude in newTree) { if (oldTree[prelude] === undefined) { // Whole media query is new. for (var selector in newTree[prelude]) { var rule = new VRule(selector, prelude); rule.diff(newTree[prelude][selector]); newTree[prelude][selector] = rule; } } else { // Old tree already has rules with this media query. var oldRules = oldTree[prelude]; var newRules = newTree[prelude]; // Remove rules not present in new tree. for (var selector in oldRules) if (!newRules[selector]) oldRules[selector].del(); // Apply new rules. for (var selector in newRules) { var rule = oldRules[selector]; if (rule) { rule.diff(newRules[selector]); newRules[selector] = rule; } else { rule = new VRule(selector, prelude); rule.diff(newRules[selector]); newRules[selector] = rule; } } } } this.tree = newTree; }; renderer.VRule = VRule; renderer.VSheet = VSheet; };