From 3374efe7624463f7a1c5375d2cff57ee072f683e Mon Sep 17 00:00:00 2001 From: ezsh <ezsh.junk@gmail.com> Date: Tue, 28 May 2019 02:26:37 +0200 Subject: [PATCH] Make mergeRules work with hierarchical objects --- src/js/rulesAssistant.js | 58 +++++++++++++++++++++++++++++----------- 1 file changed, 43 insertions(+), 15 deletions(-) diff --git a/src/js/rulesAssistant.js b/src/js/rulesAssistant.js index 648662d4f70..047aa8bde13 100644 --- a/src/js/rulesAssistant.js +++ b/src/js/rulesAssistant.js @@ -58,23 +58,51 @@ window.lastPregRule = function(slave, rules) { }; /** - * @param {App.RA.Rule[]} rules + * @param {App.RA.RuleSetters[]} rules * @returns {App.RA.RuleSetters} */ -window.mergeRules = function (rules) { - const combinedRule = {}; - rules.forEach(rule => { - // A rule overrides any preceding ones if, - // * there are no preceding ones, - // * or it sets autoBrand, - // * or it does not set autoBrand and is not null - Object.keys(rule).forEach(key => { - const applies = (combinedRule[key] === undefined || - (key === "autoBrand" && rule[key]) || - (key !== "autoBrand" && rule[key] !== null)); - if (!applies) return; - combinedRule[key] = rule[key]; - }); +window.mergeRules = function(rules) { + if (rules.length === 0) { + return emptyDefaultRule().set; + } else if (rules.length === 1) { + return rules[0]; + } + + function isObject(o) { + return (o !== undefined && o !== null && typeof o === 'object' && !Array.isArray(o)); + } + + function deepAssign(target, source) { + for (const key in source) { + if (!source.hasOwnProperty(key)) { + continue; + } + if (isObject(source[key])) { + if (!target.hasOwnProperty(key) || target[key] === null) { + target[key] = {}; + } + deepAssign(target[key], source[key]); + } else { + // A rule overrides any preceding ones if, + // * there are no preceding ones, + // * or it sets autoBrand, + // * or it does not set autoBrand and is not null + const overrides = ( + target[key] === undefined || target[key] === null || + (key === "autoBrand" && source[key]) || + (key !== "autoBrand" && source[key] !== null)); + if (overrides) { + target[key] = source[key]; + } + } + } + } + + const combinedRule = rules[0]; + const otherRules = rules.slice(1); + + otherRules.forEach(rule => { + deepAssign(combinedRule, rule); }); return combinedRule; }; -- GitLab