diff --git a/packages/core/src/pattern-config.mjs b/packages/core/src/pattern-config.mjs index 8b87c0450d8..7bac6c6fd2b 100644 --- a/packages/core/src/pattern-config.mjs +++ b/packages/core/src/pattern-config.mjs @@ -1,4 +1,4 @@ -import { __addNonEnumProp, capitalize } from './utils.mjs' +import { __addNonEnumProp } from './utils.mjs' export const hidePresets = { HIDE_ALL: { @@ -339,34 +339,56 @@ PatternConfig.prototype.__addPartPlugins = function (part) { // the two types of dependencies const depTypes = ['from', 'after'] +// the two lists of special istructions const exceptionTypes = ['never', 'always'] +/** + * Resolve the hiding configuration of this part + * This method does not hide dependencies, + * but it does hide or unhide parts listed in `never` and `always` in the config + * according to this part's options priority + * @param {Part} part the part whose config should be resolved + * @private + */ PatternConfig.prototype.__resolvePartHiding = function (part) { + // get the config let hide = part.hide + // if it's a string, get the preset by that name if (typeof hide === 'string') hide = hidePresets[hide] + // no config, nothing to do if (!hide) return // get the part's option priority const partDistance = this.__mutated.partDistance?.[part.name] + // get the current distances that dictate if this part should never or always be hidden const neverDistance = this.__hiding.never[part.name] || Infinity const alwaysDistance = this.__hiding.always[part.name] || Infinity + // if the part is configured to hide, and it takes priority over other instructions, hide it if (hide.self && (neverDistance > partDistance || alwaysDistance <= neverDistance)) this.partHide[part.name] = true + // for each exception list, starting with never exceptionTypes.forEach((e, i) => { + // if there are instructions for this list if (hide[e]) { + // each part in the list hide[e].forEach((p) => { + // get the current distance of a call to never or always hide this part const otherDistance = this.__hiding[exceptionTypes[Math.abs(i - 1)]][p] || Infinity + // if a current command is less important than this one, if (otherDistance > partDistance) { const thisDistance = this.__hiding[e][p] || Infinity + // record the new priority this.__hiding[e][p] = Math.min(thisDistance, partDistance) + // hide or show the part this.partHide[p] = i == 1 } }) } }) + // add the dependency hiding instructions if they haven't already been set depTypes.concat('inherited').forEach((k) => { if (this.__hiding[k][part.name] === undefined) this.__hiding[k][part.name] = hide[k] }) @@ -446,16 +468,22 @@ PatternConfig.prototype.__addDependency = function (dependencyList, partName, de * @private */ PatternConfig.prototype.__handlePartDependencyOfType = function (part, depName, depType) { + // if this dependency should be hidden based on dependency type, and doesn't already have an instruction, hide it if (this.__hiding[depType][part.name] === true && this.partHide[depName] === undefined) { this.partHide[depName] = true } + // get the part's inherited hide instructions const hideInherited = this.__hiding.inherited[part.name] + // for from dependencies if (depType === 'from') { + // inject the dependency into the part this.inject[part.name] = depName + // hide after dependencies if inherited dependencies should hide this.__hiding.after[depName] = hideInherited } + // for all depependency types, from and inherited are dictated by the dependendent part's policy this.__hiding.from[depName] = hideInherited this.__hiding.inherited[depName] = hideInherited } diff --git a/packages/core/tests/pattern-part-hiding.test.mjs b/packages/core/tests/pattern-part-hiding.test.mjs index 9590f0d62b1..7ed763a3cda 100644 --- a/packages/core/tests/pattern-part-hiding.test.mjs +++ b/packages/core/tests/pattern-part-hiding.test.mjs @@ -6,7 +6,6 @@ function hidePartMatcher(partName) { const isHidden = this._obj.__isPartHidden(partName) if (!this._obj.config.parts[partName]) { throw new chai.AssertionError(`expected part \`${partName}\` to exist in pattern`) - this.fail() } this.assert( isHidden, @@ -19,7 +18,6 @@ function hidePartsMatcher(...partNames) { const hiddens = partNames.map((n) => { if (!this._obj.config.parts[n]) { throw new chai.AssertionError(`expected part \`${n}\` to exist in pattern`) - this.fail() } return this._obj.__isPartHidden(n) })