mirror of
https://github.com/chartjs/Chart.js.git
synced 2024-10-06 12:19:08 +02:00
Proxy: Only create scopes when setting values (#8799)
This commit is contained in:
parent
a4cc21f9a9
commit
74f118818b
@ -6,10 +6,11 @@ import {defined, isArray, isFunction, isObject, resolveObjectKey, _capitalize} f
|
||||
* @param {string[]} [prefixes] - The prefixes for values, in resolution order.
|
||||
* @param {object[]} [rootScopes] - The root option scopes
|
||||
* @param {string|boolean} [fallback] - Parent scopes fallback
|
||||
* @param {function} [getTarget] - callback for getting the target for changed values
|
||||
* @returns Proxy
|
||||
* @private
|
||||
*/
|
||||
export function _createResolver(scopes, prefixes = [''], rootScopes = scopes, fallback) {
|
||||
export function _createResolver(scopes, prefixes = [''], rootScopes = scopes, fallback, getTarget = () => scopes[0]) {
|
||||
if (!defined(fallback)) {
|
||||
fallback = _resolve('_fallback', scopes);
|
||||
}
|
||||
@ -19,6 +20,7 @@ export function _createResolver(scopes, prefixes = [''], rootScopes = scopes, fa
|
||||
_scopes: scopes,
|
||||
_rootScopes: rootScopes,
|
||||
_fallback: fallback,
|
||||
_getTarget: getTarget,
|
||||
override: (scope) => _createResolver([scope, ...scopes], prefixes, rootScopes, fallback),
|
||||
};
|
||||
return new Proxy(cache, {
|
||||
@ -73,7 +75,8 @@ export function _createResolver(scopes, prefixes = [''], rootScopes = scopes, fa
|
||||
* A trap for setting property values.
|
||||
*/
|
||||
set(target, prop, value) {
|
||||
scopes[0][prop] = value; // set to top level scope
|
||||
const storage = target._storage || (target._storage = getTarget());
|
||||
storage[prop] = value; // set to top level scope
|
||||
delete target[prop]; // remove from cache
|
||||
delete target._keys; // remove cached keys
|
||||
return true;
|
||||
@ -276,11 +279,6 @@ function createSubResolver(parentScopes, resolver, prop, value) {
|
||||
const fallback = resolveFallback(resolver._fallback, prop, value);
|
||||
const allScopes = [...parentScopes, ...rootScopes];
|
||||
const set = new Set();
|
||||
const firstParent = parentScopes[0];
|
||||
if (isObject(firstParent) && !(prop in firstParent)) {
|
||||
// create an empty scope for possible stored values, so we always set the values in top scope.
|
||||
set.add(firstParent[prop] = {});
|
||||
}
|
||||
set.add(value);
|
||||
let key = addScopesFromKey(set, allScopes, prop, fallback || prop);
|
||||
if (key === null) {
|
||||
@ -292,7 +290,13 @@ function createSubResolver(parentScopes, resolver, prop, value) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return _createResolver([...set], [''], rootScopes, fallback);
|
||||
return _createResolver([...set], [''], rootScopes, fallback, () => {
|
||||
const parent = resolver._getTarget();
|
||||
if (!(prop in parent)) {
|
||||
parent[prop] = {};
|
||||
}
|
||||
return parent[prop];
|
||||
});
|
||||
}
|
||||
|
||||
function addScopesFromKey(set, allScopes, key, fallback) {
|
||||
|
@ -99,6 +99,15 @@ describe('Chart.helpers.config', function() {
|
||||
expect(resolver.getter).toEqual('options getter');
|
||||
});
|
||||
|
||||
it('should not fail on when options are frozen', function() {
|
||||
function create() {
|
||||
const defaults = Object.freeze({default: true});
|
||||
const options = Object.freeze({value: true});
|
||||
return _createResolver([options, defaults]);
|
||||
}
|
||||
expect(create).not.toThrow();
|
||||
});
|
||||
|
||||
describe('_fallback', function() {
|
||||
it('should follow simple _fallback', function() {
|
||||
const defaults = {
|
||||
@ -497,6 +506,16 @@ describe('Chart.helpers.config', function() {
|
||||
expect(options.sub.value).toBeFalse();
|
||||
expect(defaults.sub.value).toBeTrue();
|
||||
});
|
||||
|
||||
it('should throw when setting a value and options is frozen', function() {
|
||||
const defaults = Object.freeze({default: true});
|
||||
const options = Object.freeze({value: true});
|
||||
const resolver = _createResolver([options, defaults]);
|
||||
function set() {
|
||||
resolver.value = false;
|
||||
}
|
||||
expect(set).toThrow();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user