Skip to content

Commit

Permalink
Merge branch 'master' into change-file-to-filePath
Browse files Browse the repository at this point in the history
  • Loading branch information
Casheeew authored Dec 19, 2023
2 parents 374ef9e + 6b07b1e commit b708220
Show file tree
Hide file tree
Showing 17 changed files with 288 additions and 267 deletions.
7 changes: 5 additions & 2 deletions ext/js/app/content-script-main.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,8 @@ import {yomitan} from '../yomitan.js';
import {Frontend} from './frontend.js';
import {PopupFactory} from './popup-factory.js';

(async () => {
/** Entry point. */
async function main() {
try {
await yomitan.prepare();

Expand Down Expand Up @@ -57,4 +58,6 @@ import {PopupFactory} from './popup-factory.js';
} catch (e) {
log.error(e);
}
})();
}

await main();
9 changes: 6 additions & 3 deletions ext/js/background/background-main.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,12 @@
import {yomitan} from '../yomitan.js';
import {Backend} from './backend.js';

(() => {
/** Entry point. */
async function main() {
yomitan.prepare(true);

const backend = new Backend();
backend.prepare();
})();
await backend.prepare();
}

main();
7 changes: 5 additions & 2 deletions ext/js/background/offscreen-main.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,9 @@

import {Offscreen} from './offscreen.js';

(() => {
/** Entry point. */
async function main() {
new Offscreen();
})();
}

await main();
298 changes: 139 additions & 159 deletions ext/js/core.js
Original file line number Diff line number Diff line change
Expand Up @@ -53,200 +53,180 @@ export function stringReverse(string) {
* @returns {T} A new clone of the value.
* @throws An error if the value is circular and cannot be cloned.
*/
export const clone = (() => {
/**
* @template T
* @param {T} value
* @returns {T}
*/
// eslint-disable-next-line no-shadow, @typescript-eslint/no-shadow
function clone(value) {
if (value === null) { return /** @type {T} */ (null); }
switch (typeof value) {
case 'boolean':
case 'number':
case 'string':
case 'bigint':
case 'symbol':
case 'undefined':
return value;
default:
return cloneInternal(value, new Set());
}
export function clone(value) {
if (value === null) { return /** @type {T} */ (null); }
switch (typeof value) {
case 'boolean':
case 'number':
case 'string':
case 'bigint':
case 'symbol':
case 'undefined':
return value;
default:
return cloneInternal(value, new Set());
}
}

/**
* @template [T=unknown]
* @param {T} value
* @param {Set<unknown>} visited
* @returns {T}
* @throws {Error}
*/
function cloneInternal(value, visited) {
if (value === null) { return /** @type {T} */ (null); }
switch (typeof value) {
case 'boolean':
case 'number':
case 'string':
case 'bigint':
case 'symbol':
case 'undefined':
return value;
case 'object':
return /** @type {T} */ (
/**
* @template [T=unknown]
* @param {T} value
* @param {Set<unknown>} visited
* @returns {T}
* @throws {Error}
*/
function cloneInternal(value, visited) {
if (value === null) { return /** @type {T} */ (null); }
switch (typeof value) {
case 'boolean':
case 'number':
case 'string':
case 'bigint':
case 'symbol':
case 'undefined':
return value;
case 'object':
return /** @type {T} */ (
Array.isArray(value) ?
cloneArray(value, visited) :
cloneObject(/** @type {import('core').SerializableObject} */ (value), visited)
);
default:
throw new Error(`Cannot clone object of type ${typeof value}`);
}
);
default:
throw new Error(`Cannot clone object of type ${typeof value}`);
}
}

/**
* @param {unknown[]} value
* @param {Set<unknown>} visited
* @returns {unknown[]}
* @throws {Error}
*/
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);
/**
* @param {unknown[]} value
* @param {Set<unknown>} visited
* @returns {unknown[]}
* @throws {Error}
*/
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);
}
}

/**
* @param {import('core').SerializableObject} value
* @param {Set<unknown>} visited
* @returns {import('core').SerializableObject}
* @throws {Error}
*/
function cloneObject(value, visited) {
if (visited.has(value)) { throw new Error('Circular'); }
try {
visited.add(value);
/** @type {import('core').SerializableObject} */
const result = {};
for (const key in value) {
if (Object.prototype.hasOwnProperty.call(value, key)) {
result[key] = cloneInternal(value[key], visited);
}
/**
* @param {import('core').SerializableObject} value
* @param {Set<unknown>} visited
* @returns {import('core').SerializableObject}
* @throws {Error}
*/
function cloneObject(value, visited) {
if (visited.has(value)) { throw new Error('Circular'); }
try {
visited.add(value);
/** @type {import('core').SerializableObject} */
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 result;
} finally {
visited.delete(value);
}

return clone;
})();
}

/**
* Checks if an object or value is deeply equal to another object or value.
* @param {unknown} value1 The first value to check.
* @param {unknown} value2 The second value to check.
* @returns {boolean} `true` if the values are the same object, or deeply equal without cycles. `false` otherwise.
*/
export const deepEqual = (() => {
/**
* @param {unknown} value1
* @param {unknown} value2
* @returns {boolean}
*/
// eslint-disable-next-line no-shadow, @typescript-eslint/no-shadow
function deepEqual(value1, value2) {
if (value1 === value2) { return true; }

const type = typeof value1;
if (typeof value2 !== type) { return false; }

switch (type) {
case 'object':
case 'function':
return deepEqualInternal(value1, value2, new Set());
default:
return false;
}
export function deepEqual(value1, value2) {
if (value1 === value2) { return true; }

const type = typeof value1;
if (typeof value2 !== type) { return false; }

switch (type) {
case 'object':
case 'function':
return deepEqualInternal(value1, value2, new Set());
default:
return false;
}
}

/**
* @param {unknown} value1
* @param {unknown} value2
* @param {Set<unknown>} visited1
* @returns {boolean}
*/
function deepEqualInternal(value1, value2, visited1) {
if (value1 === value2) { return true; }

const type = typeof value1;
if (typeof value2 !== type) { return false; }

switch (type) {
case 'object':
case 'function':
{
if (value1 === null || value2 === null) { return false; }
const array = Array.isArray(value1);
if (array !== Array.isArray(value2)) { return false; }
if (visited1.has(value1)) { return false; }
visited1.add(value1);
return (
/**
* @param {unknown} value1
* @param {unknown} value2
* @param {Set<unknown>} visited1
* @returns {boolean}
*/
function deepEqualInternal(value1, value2, visited1) {
if (value1 === value2) { return true; }

const type = typeof value1;
if (typeof value2 !== type) { return false; }

switch (type) {
case 'object':
case 'function':
{
if (value1 === null || value2 === null) { return false; }
const array = Array.isArray(value1);
if (array !== Array.isArray(value2)) { return false; }
if (visited1.has(value1)) { return false; }
visited1.add(value1);
return (
array ?
areArraysEqual(/** @type {unknown[]} */ (value1), /** @type {unknown[]} */ (value2), visited1) :
areObjectsEqual(/** @type {import('core').UnknownObject} */ (value1), /** @type {import('core').UnknownObject} */ (value2), visited1)
);
}
default:
return false;
);
}
default:
return false;
}
}

/**
* @param {import('core').UnknownObject} value1
* @param {import('core').UnknownObject} value2
* @param {Set<unknown>} visited1
* @returns {boolean}
*/
function areObjectsEqual(value1, value2, visited1) {
const keys1 = Object.keys(value1);
const keys2 = Object.keys(value2);
if (keys1.length !== keys2.length) { return false; }

const keys1Set = new Set(keys1);
for (const key of keys2) {
if (!keys1Set.has(key) || !deepEqualInternal(value1[key], value2[key], visited1)) { return false; }
}
/**
* @param {import('core').UnknownObject} value1
* @param {import('core').UnknownObject} value2
* @param {Set<unknown>} visited1
* @returns {boolean}
*/
function areObjectsEqual(value1, value2, visited1) {
const keys1 = Object.keys(value1);
const keys2 = Object.keys(value2);
if (keys1.length !== keys2.length) { return false; }

return true;
const keys1Set = new Set(keys1);
for (const key of keys2) {
if (!keys1Set.has(key) || !deepEqualInternal(value1[key], value2[key], visited1)) { return false; }
}

/**
* @param {unknown[]} value1
* @param {unknown[]} value2
* @param {Set<unknown>} visited1
* @returns {boolean}
*/
function areArraysEqual(value1, value2, visited1) {
const length = value1.length;
if (length !== value2.length) { return false; }
return true;
}

for (let i = 0; i < length; ++i) {
if (!deepEqualInternal(value1[i], value2[i], visited1)) { return false; }
}
/**
* @param {unknown[]} value1
* @param {unknown[]} value2
* @param {Set<unknown>} visited1
* @returns {boolean}
*/
function areArraysEqual(value1, value2, visited1) {
const length = value1.length;
if (length !== value2.length) { return false; }

return true;
for (let i = 0; i < length; ++i) {
if (!deepEqualInternal(value1[i], value2[i], visited1)) { return false; }
}

return deepEqual;
})();
return true;
}

/**
* Creates a new base-16 (lower case) string of a sequence of random bytes of the given length.
Expand Down
Loading

0 comments on commit b708220

Please sign in to comment.