* Routes the named defaults to fallback to another scope/name. * This routing is useful when those target values, like defaults.color, are changed runtime. * If the values would be copied, the runtime change would not take effect. By routing, the * fallback is evaluated at each access, so its
(scope, name, targetScope, targetName)
| 128 | * @param {string} targetName The target name in the target scope the property should be routed to. |
| 129 | */ |
| 130 | route(scope, name, targetScope, targetName) { |
| 131 | const scopeObject = getScope(this, scope); |
| 132 | const targetScopeObject = getScope(this, targetScope); |
| 133 | const privateName = '_' + name; |
| 134 | |
| 135 | Object.defineProperties(scopeObject, { |
| 136 | // A private property is defined to hold the actual value, when this property is set in its scope (set in the setter) |
| 137 | [privateName]: { |
| 138 | value: scopeObject[name], |
| 139 | writable: true |
| 140 | }, |
| 141 | // The actual property is defined as getter/setter so we can do the routing when value is not locally set. |
| 142 | [name]: { |
| 143 | enumerable: true, |
| 144 | get() { |
| 145 | const local = this[privateName]; |
| 146 | const target = targetScopeObject[targetName]; |
| 147 | if (isObject(local)) { |
| 148 | return Object.assign({}, target, local); |
| 149 | } |
| 150 | return valueOrDefault(local, target); |
| 151 | }, |
| 152 | set(value) { |
| 153 | this[privateName] = value; |
| 154 | } |
| 155 | } |
| 156 | }); |
| 157 | } |
| 158 | |
| 159 | apply(appliers) { |
| 160 | appliers.forEach((apply) => apply(this)); |
nothing calls this directly
no test coverage detected