Clone function (#624)
* Add clone function * Replace utilIsolate with clone * Replace JsonSchema.isolate with clone function * Include core.js for tests which use json-schema.js * Update visisted set
This commit is contained in:
parent
5bf805755a
commit
cdf191336a
@ -99,6 +99,7 @@
|
|||||||
"getSetDifference": "readonly",
|
"getSetDifference": "readonly",
|
||||||
"escapeRegExp": "readonly",
|
"escapeRegExp": "readonly",
|
||||||
"deferPromise": "readonly",
|
"deferPromise": "readonly",
|
||||||
|
"clone": "readonly",
|
||||||
"EventDispatcher": "readonly",
|
"EventDispatcher": "readonly",
|
||||||
"EventListenerCollection": "readonly",
|
"EventListenerCollection": "readonly",
|
||||||
"EXTENSION_IS_BROWSER_EDGE": "readonly"
|
"EXTENSION_IS_BROWSER_EDGE": "readonly"
|
||||||
|
@ -38,7 +38,6 @@
|
|||||||
* profileConditionsDescriptorPromise
|
* profileConditionsDescriptorPromise
|
||||||
* requestJson
|
* requestJson
|
||||||
* requestText
|
* requestText
|
||||||
* utilIsolate
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
class Backend {
|
class Backend {
|
||||||
@ -875,7 +874,7 @@ class Backend {
|
|||||||
for (const target of targets) {
|
for (const target of targets) {
|
||||||
try {
|
try {
|
||||||
const result = this._modifySetting(target);
|
const result = this._modifySetting(target);
|
||||||
results.push({result: utilIsolate(result)});
|
results.push({result: clone(result)});
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
results.push({error: errorToJson(e)});
|
results.push({error: errorToJson(e)});
|
||||||
}
|
}
|
||||||
@ -889,7 +888,7 @@ class Backend {
|
|||||||
for (const target of targets) {
|
for (const target of targets) {
|
||||||
try {
|
try {
|
||||||
const result = this._getSetting(target);
|
const result = this._getSetting(target);
|
||||||
results.push({result: utilIsolate(result)});
|
results.push({result: clone(result)});
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
results.push({error: errorToJson(e)});
|
results.push({error: errorToJson(e)});
|
||||||
}
|
}
|
||||||
|
@ -90,7 +90,7 @@ class JsonSchemaProxyHandler {
|
|||||||
throw new Error(`Property ${property} not supported`);
|
throw new Error(`Property ${property} not supported`);
|
||||||
}
|
}
|
||||||
|
|
||||||
value = JsonSchema.isolate(value);
|
value = JsonSchema.clone(value);
|
||||||
|
|
||||||
JsonSchemaProxyHandler.validate(value, propertySchema, new JsonSchemaTraversalInfo(value, propertySchema));
|
JsonSchemaProxyHandler.validate(value, propertySchema, new JsonSchemaTraversalInfo(value, propertySchema));
|
||||||
|
|
||||||
@ -515,7 +515,7 @@ class JsonSchemaProxyHandler {
|
|||||||
|
|
||||||
const schemaDefault = schema.default;
|
const schemaDefault = schema.default;
|
||||||
if (typeof schemaDefault !== 'undefined') {
|
if (typeof schemaDefault !== 'undefined') {
|
||||||
value = JsonSchema.isolate(schemaDefault);
|
value = JsonSchema.clone(schemaDefault);
|
||||||
type = JsonSchemaProxyHandler.getValueType(value);
|
type = JsonSchemaProxyHandler.getValueType(value);
|
||||||
assignDefault = !JsonSchemaProxyHandler.isValueTypeAny(value, type, schemaType);
|
assignDefault = !JsonSchemaProxyHandler.isValueTypeAny(value, type, schemaType);
|
||||||
}
|
}
|
||||||
@ -628,19 +628,7 @@ class JsonSchema {
|
|||||||
return JsonSchemaProxyHandler.getValidValueOrDefault(schema, value);
|
return JsonSchemaProxyHandler.getValidValueOrDefault(schema, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
static isolate(value) {
|
static clone(value) {
|
||||||
if (value === null) { return null; }
|
return clone(value);
|
||||||
|
|
||||||
switch (typeof value) {
|
|
||||||
case 'boolean':
|
|
||||||
case 'number':
|
|
||||||
case 'string':
|
|
||||||
case 'bigint':
|
|
||||||
case 'symbol':
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
|
|
||||||
const stringValue = JSON.stringify(value);
|
|
||||||
return typeof stringValue === 'string' ? JSON.parse(stringValue) : null;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -15,26 +15,10 @@
|
|||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
function utilIsolate(value) {
|
|
||||||
if (value === null) { return null; }
|
|
||||||
|
|
||||||
switch (typeof value) {
|
|
||||||
case 'boolean':
|
|
||||||
case 'number':
|
|
||||||
case 'string':
|
|
||||||
case 'bigint':
|
|
||||||
case 'symbol':
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
|
|
||||||
const stringValue = JSON.stringify(value);
|
|
||||||
return typeof stringValue === 'string' ? JSON.parse(stringValue) : null;
|
|
||||||
}
|
|
||||||
|
|
||||||
function utilFunctionIsolate(func) {
|
function utilFunctionIsolate(func) {
|
||||||
return function isolatedFunction(...args) {
|
return function isolatedFunction(...args) {
|
||||||
try {
|
try {
|
||||||
args = args.map((v) => utilIsolate(v));
|
args = args.map((v) => clone(v));
|
||||||
return func.call(this, ...args);
|
return func.call(this, ...args);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
try {
|
try {
|
||||||
@ -50,7 +34,7 @@ function utilFunctionIsolate(func) {
|
|||||||
|
|
||||||
function utilBackgroundIsolate(data) {
|
function utilBackgroundIsolate(data) {
|
||||||
const backgroundPage = chrome.extension.getBackgroundPage();
|
const backgroundPage = chrome.extension.getBackgroundPage();
|
||||||
return backgroundPage.utilIsolate(data);
|
return backgroundPage.clone(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
function utilBackgroundFunctionIsolate(func) {
|
function utilBackgroundFunctionIsolate(func) {
|
||||||
|
@ -157,6 +157,73 @@ function getSetDifference(set1, set2) {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const clone = (() => {
|
||||||
|
// eslint-disable-next-line no-shadow
|
||||||
|
function clone(value) {
|
||||||
|
if (value === null) { return null; }
|
||||||
|
switch (typeof value) {
|
||||||
|
case 'boolean':
|
||||||
|
case 'number':
|
||||||
|
case 'string':
|
||||||
|
case 'bigint':
|
||||||
|
case 'symbol':
|
||||||
|
case 'undefined':
|
||||||
|
return value;
|
||||||
|
default:
|
||||||
|
return cloneInternal(value, new Set());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function cloneInternal(value, visited) {
|
||||||
|
if (value === null) { return null; }
|
||||||
|
switch (typeof value) {
|
||||||
|
case 'boolean':
|
||||||
|
case 'number':
|
||||||
|
case 'string':
|
||||||
|
case 'bigint':
|
||||||
|
case 'symbol':
|
||||||
|
case 'undefined':
|
||||||
|
return value;
|
||||||
|
case 'function':
|
||||||
|
return cloneObject(value, visited);
|
||||||
|
case 'object':
|
||||||
|
return Array.isArray(value) ? cloneArray(value, visited) : cloneObject(value, visited);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function cloneArray(value, visited) {
|
||||||
|
if (visited.has(value)) { throw new Error('Circular'); }
|
||||||
|
try {
|
||||||
|
visited.add(value);
|
||||||
|
const result = [];
|
||||||
|
for (const item of value) {
|
||||||
|
result.push(cloneInternal(item, visited));
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
} finally {
|
||||||
|
visited.delete(value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function cloneObject(value, visited) {
|
||||||
|
if (visited.has(value)) { throw new Error('Circular'); }
|
||||||
|
try {
|
||||||
|
visited.add(value);
|
||||||
|
const result = {};
|
||||||
|
for (const key in value) {
|
||||||
|
if (Object.prototype.hasOwnProperty.call(value, key)) {
|
||||||
|
result[key] = cloneInternal(value[key], visited);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
} finally {
|
||||||
|
visited.delete(value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return clone;
|
||||||
|
})();
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Async utilities
|
* Async utilities
|
||||||
|
@ -21,7 +21,10 @@ const {JSZip} = require('./yomichan-test');
|
|||||||
const {VM} = require('./yomichan-vm');
|
const {VM} = require('./yomichan-vm');
|
||||||
|
|
||||||
const vm = new VM();
|
const vm = new VM();
|
||||||
vm.execute('bg/js/json-schema.js');
|
vm.execute([
|
||||||
|
'mixed/js/core.js',
|
||||||
|
'bg/js/json-schema.js'
|
||||||
|
]);
|
||||||
const JsonSchema = vm.get('JsonSchema');
|
const JsonSchema = vm.get('JsonSchema');
|
||||||
|
|
||||||
|
|
||||||
|
@ -19,7 +19,10 @@ const fs = require('fs');
|
|||||||
const {VM} = require('./yomichan-vm');
|
const {VM} = require('./yomichan-vm');
|
||||||
|
|
||||||
const vm = new VM();
|
const vm = new VM();
|
||||||
vm.execute('bg/js/json-schema.js');
|
vm.execute([
|
||||||
|
'mixed/js/core.js',
|
||||||
|
'bg/js/json-schema.js'
|
||||||
|
]);
|
||||||
const JsonSchema = vm.get('JsonSchema');
|
const JsonSchema = vm.get('JsonSchema');
|
||||||
|
|
||||||
|
|
||||||
|
@ -19,7 +19,10 @@ const assert = require('assert');
|
|||||||
const {VM} = require('./yomichan-vm');
|
const {VM} = require('./yomichan-vm');
|
||||||
|
|
||||||
const vm = new VM();
|
const vm = new VM();
|
||||||
vm.execute('bg/js/json-schema.js');
|
vm.execute([
|
||||||
|
'mixed/js/core.js',
|
||||||
|
'bg/js/json-schema.js'
|
||||||
|
]);
|
||||||
const JsonSchema = vm.get('JsonSchema');
|
const JsonSchema = vm.get('JsonSchema');
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user