summaryrefslogtreecommitdiff
path: root/ext/js/background
diff options
context:
space:
mode:
authortoasted-nutbread <toasted-nutbread@users.noreply.github.com>2024-01-31 08:38:30 -0500
committerGitHub <noreply@github.com>2024-01-31 13:38:30 +0000
commit87ed7c8affd3ade9d3cd2d9ed1a61dd5f224e473 (patch)
treebe727294e31ef21e8a3f634734610e69e4a155ac /ext/js/background
parent3e419aa562aab03ca20421aaf7e4d1a39194a5b4 (diff)
Module refactoring (#588)
* Convert PronunciationGenerator into static functions * Convert DictionaryDataUtil into static functions * Convert AnkiNoteDataCreator into static functions * Convert MediaUtil into static functions * Convert RegexUtil into static functions * Convert StringUtil into static functions * Convert ArrayBufferUtil into static functions * Convert AnkiUtil into static functions * Convert PermissionsUtil into static functions * Convert ProfileConditionsUtil into static functions
Diffstat (limited to 'ext/js/background')
-rw-r--r--ext/js/background/backend.js38
-rw-r--r--ext/js/background/offscreen-proxy.js4
-rw-r--r--ext/js/background/offscreen.js4
-rw-r--r--ext/js/background/profile-conditions-util.js662
4 files changed, 347 insertions, 361 deletions
diff --git a/ext/js/background/backend.js b/ext/js/background/backend.js
index 0773dc4b..b95626f5 100644
--- a/ext/js/background/backend.js
+++ b/ext/js/background/backend.js
@@ -26,19 +26,19 @@ import {ExtensionError} from '../core/extension-error.js';
import {readResponseJson} from '../core/json.js';
import {log} from '../core/logger.js';
import {clone, deferPromise, isObject, promiseTimeout} from '../core/utilities.js';
-import {AnkiUtil} from '../data/anki-util.js';
+import {isNoteDataValid} from '../data/anki-util.js';
import {OptionsUtil} from '../data/options-util.js';
-import {PermissionsUtil} from '../data/permissions-util.js';
-import {ArrayBufferUtil} from '../data/sandbox/array-buffer-util.js';
+import {getAllPermissions, hasPermissions, hasRequiredPermissionsForOptions} from '../data/permissions-util.js';
+import {arrayBufferToBase64} from '../data/sandbox/array-buffer-util.js';
import {DictionaryDatabase} from '../dictionary/dictionary-database.js';
import {Environment} from '../extension/environment.js';
import {ObjectPropertyAccessor} from '../general/object-property-accessor.js';
import {distributeFuriganaInflected, isCodePointJapanese, isStringPartiallyJapanese, convertKatakanaToHiragana as jpConvertKatakanaToHiragana} from '../language/japanese.js';
import {Translator} from '../language/translator.js';
import {AudioDownloader} from '../media/audio-downloader.js';
-import {MediaUtil} from '../media/media-util.js';
+import {getFileExtensionFromAudioMediaType, getFileExtensionFromImageMediaType} from '../media/media-util.js';
import {ClipboardReaderProxy, DictionaryDatabaseProxy, OffscreenProxy, TranslatorProxy} from './offscreen-proxy.js';
-import {ProfileConditionsUtil} from './profile-conditions-util.js';
+import {createSchema, normalizeContext} from './profile-conditions-util.js';
import {RequestBuilder} from './request-builder.js';
import {injectStylesheet} from './script-manager.js';
@@ -95,8 +95,6 @@ export class Backend {
this._options = null;
/** @type {import('../data/json-schema.js').JsonSchema[]} */
this._profileConditionsSchemaCache = [];
- /** @type {ProfileConditionsUtil} */
- this._profileConditionsUtil = new ProfileConditionsUtil();
/** @type {?string} */
this._defaultAnkiFieldTemplates = null;
/** @type {RequestBuilder} */
@@ -138,8 +136,6 @@ export class Backend {
this._logErrorLevel = null;
/** @type {?chrome.permissions.Permissions} */
this._permissions = null;
- /** @type {PermissionsUtil} */
- this._permissionsUtil = new PermissionsUtil();
/** @type {Map<string, (() => void)[]>} */
this._applicationReadyHandlers = new Map();
@@ -259,7 +255,7 @@ export class Backend {
try {
this._prepareInternalSync();
- this._permissions = await this._permissionsUtil.getAllPermissions();
+ this._permissions = await getAllPermissions();
this._defaultBrowserActionTitle = await this._getBrowserIconTitle();
this._badgePrepareDelayTimer = setTimeout(() => {
this._badgePrepareDelayTimer = null;
@@ -545,7 +541,7 @@ export class Backend {
for (let i = 0; i < notes.length; ++i) {
const note = notes[i];
let canAdd = canAddArray[i];
- const valid = AnkiUtil.isNoteDataValid(note);
+ const valid = isNoteDataValid(note);
if (!valid) { canAdd = false; }
const info = {canAdd, valid, noteIds: null};
results.push(info);
@@ -815,7 +811,7 @@ export class Backend {
let permissionsOkay = false;
try {
- permissionsOkay = await this._permissionsUtil.hasPermissions({permissions: ['nativeMessaging']});
+ permissionsOkay = await hasPermissions({permissions: ['nativeMessaging']});
} catch (e) {
// NOP
}
@@ -1302,7 +1298,7 @@ export class Backend {
* @returns {?import('settings').Profile}
*/
_getProfileFromContext(options, optionsContext) {
- const normalizedOptionsContext = this._profileConditionsUtil.normalizeContext(optionsContext);
+ const normalizedOptionsContext = normalizeContext(optionsContext);
let index = 0;
for (const profile of options.profiles) {
@@ -1312,7 +1308,7 @@ export class Backend {
if (index < this._profileConditionsSchemaCache.length) {
schema = this._profileConditionsSchemaCache[index];
} else {
- schema = this._profileConditionsUtil.createSchema(conditionGroups);
+ schema = createSchema(conditionGroups);
this._profileConditionsSchemaCache.push(schema);
}
@@ -2128,7 +2124,7 @@ export class Backend {
return null;
}
- let extension = contentType !== null ? MediaUtil.getFileExtensionFromAudioMediaType(contentType) : null;
+ let extension = contentType !== null ? getFileExtensionFromAudioMediaType(contentType) : null;
if (extension === null) { extension = '.mp3'; }
let fileName = this._generateAnkiNoteMediaFileName('yomitan_audio', extension, timestamp, definitionDetails);
fileName = fileName.replace(/\]/g, '');
@@ -2147,7 +2143,7 @@ export class Backend {
const dataUrl = await this._getScreenshot(tabId, frameId, format, quality);
const {mediaType, data} = this._getDataUrlInfo(dataUrl);
- const extension = MediaUtil.getFileExtensionFromImageMediaType(mediaType);
+ const extension = getFileExtensionFromImageMediaType(mediaType);
if (extension === null) {
throw new Error('Unknown media type for screenshot image');
}
@@ -2169,7 +2165,7 @@ export class Backend {
}
const {mediaType, data} = this._getDataUrlInfo(dataUrl);
- const extension = MediaUtil.getFileExtensionFromImageMediaType(mediaType);
+ const extension = getFileExtensionFromImageMediaType(mediaType);
if (extension === null) {
throw new Error('Unknown media type for clipboard image');
}
@@ -2215,7 +2211,7 @@ export class Backend {
let fileName = null;
if (media !== null) {
const {content, mediaType} = media;
- const extension = MediaUtil.getFileExtensionFromImageMediaType(mediaType);
+ const extension = getFileExtensionFromImageMediaType(mediaType);
fileName = this._generateAnkiNoteMediaFileName(
`yomitan_dictionary_media_${i + 1}`,
extension !== null ? extension : '',
@@ -2611,7 +2607,7 @@ export class Backend {
* @returns {Promise<void>}
*/
async _checkPermissions() {
- this._permissions = await this._permissionsUtil.getAllPermissions();
+ this._permissions = await getAllPermissions();
this._updateBadge();
}
@@ -2628,7 +2624,7 @@ export class Backend {
*/
_hasRequiredPermissionsForSettings(options) {
if (!this._canObservePermissionsChanges()) { return true; }
- return this._permissions === null || this._permissionsUtil.hasRequiredPermissionsForOptions(this._permissions, options);
+ return this._permissions === null || hasRequiredPermissionsForOptions(this._permissions, options);
}
/**
@@ -2663,7 +2659,7 @@ export class Backend {
const results = [];
for (const item of await this._dictionaryDatabase.getMedia(targets)) {
const {content, dictionary, height, mediaType, path, width} = item;
- const content2 = ArrayBufferUtil.arrayBufferToBase64(content);
+ const content2 = arrayBufferToBase64(content);
results.push({content: content2, dictionary, height, mediaType, path, width});
}
return results;
diff --git a/ext/js/background/offscreen-proxy.js b/ext/js/background/offscreen-proxy.js
index 80ff31c0..716deddd 100644
--- a/ext/js/background/offscreen-proxy.js
+++ b/ext/js/background/offscreen-proxy.js
@@ -18,7 +18,7 @@
import {ExtensionError} from '../core/extension-error.js';
import {isObject} from '../core/utilities.js';
-import {ArrayBufferUtil} from '../data/sandbox/array-buffer-util.js';
+import {base64ToArrayBuffer} from '../data/sandbox/array-buffer-util.js';
export class OffscreenProxy {
/**
@@ -144,7 +144,7 @@ export class DictionaryDatabaseProxy {
*/
async getMedia(targets) {
const serializedMedia = /** @type {import('dictionary-database').Media<string>[]} */ (await this._offscreen.sendMessagePromise({action: 'databaseGetMediaOffscreen', params: {targets}}));
- const media = serializedMedia.map((m) => ({...m, content: ArrayBufferUtil.base64ToArrayBuffer(m.content)}));
+ const media = serializedMedia.map((m) => ({...m, content: base64ToArrayBuffer(m.content)}));
return media;
}
}
diff --git a/ext/js/background/offscreen.js b/ext/js/background/offscreen.js
index ef05508a..b203e326 100644
--- a/ext/js/background/offscreen.js
+++ b/ext/js/background/offscreen.js
@@ -18,7 +18,7 @@
import {ClipboardReader} from '../comm/clipboard-reader.js';
import {createApiMap, invokeApiMapHandler} from '../core/api-map.js';
-import {ArrayBufferUtil} from '../data/sandbox/array-buffer-util.js';
+import {arrayBufferToBase64} from '../data/sandbox/array-buffer-util.js';
import {DictionaryDatabase} from '../dictionary/dictionary-database.js';
import {Translator} from '../language/translator.js';
@@ -110,7 +110,7 @@ export class Offscreen {
/** @type {import('offscreen').ApiHandler<'databaseGetMediaOffscreen'>} */
async _getMediaHandler({targets}) {
const media = await this._dictionaryDatabase.getMedia(targets);
- const serializedMedia = media.map((m) => ({...m, content: ArrayBufferUtil.arrayBufferToBase64(m.content)}));
+ const serializedMedia = media.map((m) => ({...m, content: arrayBufferToBase64(m.content)}));
return serializedMedia;
}
diff --git a/ext/js/background/profile-conditions-util.js b/ext/js/background/profile-conditions-util.js
index f3be226d..e2d58725 100644
--- a/ext/js/background/profile-conditions-util.js
+++ b/ext/js/background/profile-conditions-util.js
@@ -18,379 +18,369 @@
import {JsonSchema} from '../data/json-schema.js';
+/** @type {RegExp} */
+const splitPattern = /[,;\s]+/;
+/** @type {Map<string, {operators: Map<string, import('profile-conditions-util').CreateSchemaFunction>}>} */
+const descriptors = new Map([
+ [
+ 'popupLevel',
+ {
+ operators: new Map(/** @type {import('profile-conditions-util').OperatorMapArray} */ ([
+ ['equal', createSchemaPopupLevelEqual.bind(this)],
+ ['notEqual', createSchemaPopupLevelNotEqual.bind(this)],
+ ['lessThan', createSchemaPopupLevelLessThan.bind(this)],
+ ['greaterThan', createSchemaPopupLevelGreaterThan.bind(this)],
+ ['lessThanOrEqual', createSchemaPopupLevelLessThanOrEqual.bind(this)],
+ ['greaterThanOrEqual', createSchemaPopupLevelGreaterThanOrEqual.bind(this)]
+ ]))
+ }
+ ],
+ [
+ 'url',
+ {
+ operators: new Map(/** @type {import('profile-conditions-util').OperatorMapArray} */ ([
+ ['matchDomain', createSchemaUrlMatchDomain.bind(this)],
+ ['matchRegExp', createSchemaUrlMatchRegExp.bind(this)]
+ ]))
+ }
+ ],
+ [
+ 'modifierKeys',
+ {
+ operators: new Map(/** @type {import('profile-conditions-util').OperatorMapArray} */ ([
+ ['are', createSchemaModifierKeysAre.bind(this)],
+ ['areNot', createSchemaModifierKeysAreNot.bind(this)],
+ ['include', createSchemaModifierKeysInclude.bind(this)],
+ ['notInclude', createSchemaModifierKeysNotInclude.bind(this)]
+ ]))
+ }
+ ],
+ [
+ 'flags',
+ {
+ operators: new Map(/** @type {import('profile-conditions-util').OperatorMapArray} */ ([
+ ['are', createSchemaFlagsAre.bind(this)],
+ ['areNot', createSchemaFlagsAreNot.bind(this)],
+ ['include', createSchemaFlagsInclude.bind(this)],
+ ['notInclude', createSchemaFlagsNotInclude.bind(this)]
+ ]))
+ }
+ ]
+]);
+
/**
- * Utility class to help processing profile conditions.
+ * Creates a new JSON schema descriptor for the given set of condition groups.
+ * @param {import('settings').ProfileConditionGroup[]} conditionGroups An array of condition groups.
+ * For a profile match, all of the items must return successfully in at least one of the groups.
+ * @returns {JsonSchema} A new `JsonSchema` object.
*/
-export class ProfileConditionsUtil {
- /**
- * Creates a new instance.
- */
- constructor() {
- /** @type {RegExp} */
- this._splitPattern = /[,;\s]+/;
- /** @type {Map<string, {operators: Map<string, import('profile-conditions-util').CreateSchemaFunction>}>} */
- this._descriptors = new Map([
- [
- 'popupLevel',
- {
- operators: new Map(/** @type {import('profile-conditions-util').OperatorMapArray} */ ([
- ['equal', this._createSchemaPopupLevelEqual.bind(this)],
- ['notEqual', this._createSchemaPopupLevelNotEqual.bind(this)],
- ['lessThan', this._createSchemaPopupLevelLessThan.bind(this)],
- ['greaterThan', this._createSchemaPopupLevelGreaterThan.bind(this)],
- ['lessThanOrEqual', this._createSchemaPopupLevelLessThanOrEqual.bind(this)],
- ['greaterThanOrEqual', this._createSchemaPopupLevelGreaterThanOrEqual.bind(this)]
- ]))
- }
- ],
- [
- 'url',
- {
- operators: new Map(/** @type {import('profile-conditions-util').OperatorMapArray} */ ([
- ['matchDomain', this._createSchemaUrlMatchDomain.bind(this)],
- ['matchRegExp', this._createSchemaUrlMatchRegExp.bind(this)]
- ]))
- }
- ],
- [
- 'modifierKeys',
- {
- operators: new Map(/** @type {import('profile-conditions-util').OperatorMapArray} */ ([
- ['are', this._createSchemaModifierKeysAre.bind(this)],
- ['areNot', this._createSchemaModifierKeysAreNot.bind(this)],
- ['include', this._createSchemaModifierKeysInclude.bind(this)],
- ['notInclude', this._createSchemaModifierKeysNotInclude.bind(this)]
- ]))
- }
- ],
- [
- 'flags',
- {
- operators: new Map(/** @type {import('profile-conditions-util').OperatorMapArray} */ ([
- ['are', this._createSchemaFlagsAre.bind(this)],
- ['areNot', this._createSchemaFlagsAreNot.bind(this)],
- ['include', this._createSchemaFlagsInclude.bind(this)],
- ['notInclude', this._createSchemaFlagsNotInclude.bind(this)]
- ]))
- }
- ]
- ]);
- }
+export function createSchema(conditionGroups) {
+ const anyOf = [];
+ for (const {conditions} of conditionGroups) {
+ const allOf = [];
+ for (const {type, operator, value} of conditions) {
+ const conditionDescriptor = descriptors.get(type);
+ if (typeof conditionDescriptor === 'undefined') { continue; }
- /**
- * Creates a new JSON schema descriptor for the given set of condition groups.
- * @param {import('settings').ProfileConditionGroup[]} conditionGroups An array of condition groups.
- * For a profile match, all of the items must return successfully in at least one of the groups.
- * @returns {JsonSchema} A new `JsonSchema` object.
- */
- createSchema(conditionGroups) {
- const anyOf = [];
- for (const {conditions} of conditionGroups) {
- const allOf = [];
- for (const {type, operator, value} of conditions) {
- const conditionDescriptor = this._descriptors.get(type);
- if (typeof conditionDescriptor === 'undefined') { continue; }
+ const createSchema2 = conditionDescriptor.operators.get(operator);
+ if (typeof createSchema2 === 'undefined') { continue; }
- const createSchema = conditionDescriptor.operators.get(operator);
- if (typeof createSchema === 'undefined') { continue; }
-
- const schema = createSchema(value);
- allOf.push(schema);
- }
- switch (allOf.length) {
- case 0: break;
- case 1: anyOf.push(allOf[0]); break;
- default: anyOf.push({allOf}); break;
- }
+ const schema = createSchema2(value);
+ allOf.push(schema);
}
- let schema;
- switch (anyOf.length) {
- case 0: schema = {}; break;
- case 1: schema = anyOf[0]; break;
- default: schema = {anyOf}; break;
+ switch (allOf.length) {
+ case 0: break;
+ case 1: anyOf.push(allOf[0]); break;
+ default: anyOf.push({allOf}); break;
}
- return new JsonSchema(schema);
}
+ let schema;
+ switch (anyOf.length) {
+ case 0: schema = {}; break;
+ case 1: schema = anyOf[0]; break;
+ default: schema = {anyOf}; break;
+ }
+ return new JsonSchema(schema);
+}
- /**
- * Creates a normalized version of the context object to test,
- * assigning dependent fields as needed.
- * @param {import('settings').OptionsContext} context A context object which is used during schema validation.
- * @returns {import('profile-conditions-util').NormalizedOptionsContext} A normalized context object.
- */
- normalizeContext(context) {
- const normalizedContext = /** @type {import('profile-conditions-util').NormalizedOptionsContext} */ (Object.assign({}, context));
- const {url} = normalizedContext;
- if (typeof url === 'string') {
- try {
- normalizedContext.domain = new URL(url).hostname;
- } catch (e) {
- // NOP
- }
- }
- const {flags} = normalizedContext;
- if (!Array.isArray(flags)) {
- normalizedContext.flags = [];
+/**
+ * Creates a normalized version of the context object to test,
+ * assigning dependent fields as needed.
+ * @param {import('settings').OptionsContext} context A context object which is used during schema validation.
+ * @returns {import('profile-conditions-util').NormalizedOptionsContext} A normalized context object.
+ */
+export function normalizeContext(context) {
+ const normalizedContext = /** @type {import('profile-conditions-util').NormalizedOptionsContext} */ (Object.assign({}, context));
+ const {url} = normalizedContext;
+ if (typeof url === 'string') {
+ try {
+ normalizedContext.domain = new URL(url).hostname;
+ } catch (e) {
+ // NOP
}
- return normalizedContext;
}
-
- // Private
-
- /**
- * @param {string} value
- * @returns {string[]}
- */
- _split(value) {
- return value.split(this._splitPattern);
+ const {flags} = normalizedContext;
+ if (!Array.isArray(flags)) {
+ normalizedContext.flags = [];
}
+ return normalizedContext;
+}
- /**
- * @param {string} value
- * @returns {number}
- */
- _stringToNumber(value) {
- const number = Number.parseFloat(value);
- return Number.isFinite(number) ? number : 0;
- }
+// Private
- // popupLevel schema creation functions
+/**
+ * @param {string} value
+ * @returns {string[]}
+ */
+function split(value) {
+ return value.split(splitPattern);
+}
- /**
- * @param {string} value
- * @returns {import('ext/json-schema').Schema}
- */
- _createSchemaPopupLevelEqual(value) {
- const number = this._stringToNumber(value);
- return {
- required: ['depth'],
- properties: {
- depth: {const: number}
- }
- };
- }
+/**
+ * @param {string} value
+ * @returns {number}
+ */
+function stringToNumber(value) {
+ const number = Number.parseFloat(value);
+ return Number.isFinite(number) ? number : 0;
+}
- /**
- * @param {string} value
- * @returns {import('ext/json-schema').Schema}
- */
- _createSchemaPopupLevelNotEqual(value) {
- return {
- not: {
- anyOf: [this._createSchemaPopupLevelEqual(value)]
- }
- };
- }
+// popupLevel schema creation functions
- /**
- * @param {string} value
- * @returns {import('ext/json-schema').Schema}
- */
- _createSchemaPopupLevelLessThan(value) {
- const number = this._stringToNumber(value);
- return {
- required: ['depth'],
- properties: {
- depth: {type: 'number', exclusiveMaximum: number}
- }
- };
- }
+/**
+ * @param {string} value
+ * @returns {import('ext/json-schema').Schema}
+ */
+function createSchemaPopupLevelEqual(value) {
+ const number = stringToNumber(value);
+ return {
+ required: ['depth'],
+ properties: {
+ depth: {const: number}
+ }
+ };
+}
- /**
- * @param {string} value
- * @returns {import('ext/json-schema').Schema}
- */
- _createSchemaPopupLevelGreaterThan(value) {
- const number = this._stringToNumber(value);
- return {
- required: ['depth'],
- properties: {
- depth: {type: 'number', exclusiveMinimum: number}
- }
- };
- }
+/**
+ * @param {string} value
+ * @returns {import('ext/json-schema').Schema}
+ */
+function createSchemaPopupLevelNotEqual(value) {
+ return {
+ not: {
+ anyOf: [createSchemaPopupLevelEqual(value)]
+ }
+ };
+}
- /**
- * @param {string} value
- * @returns {import('ext/json-schema').Schema}
- */
- _createSchemaPopupLevelLessThanOrEqual(value) {
- const number = this._stringToNumber(value);
- return {
- required: ['depth'],
- properties: {
- depth: {type: 'number', maximum: number}
- }
- };
- }
+/**
+ * @param {string} value
+ * @returns {import('ext/json-schema').Schema}
+ */
+function createSchemaPopupLevelLessThan(value) {
+ const number = stringToNumber(value);
+ return {
+ required: ['depth'],
+ properties: {
+ depth: {type: 'number', exclusiveMaximum: number}
+ }
+ };
+}
- /**
- * @param {string} value
- * @returns {import('ext/json-schema').Schema}
- */
- _createSchemaPopupLevelGreaterThanOrEqual(value) {
- const number = this._stringToNumber(value);
- return {
- required: ['depth'],
- properties: {
- depth: {type: 'number', minimum: number}
- }
- };
- }
+/**
+ * @param {string} value
+ * @returns {import('ext/json-schema').Schema}
+ */
+function createSchemaPopupLevelGreaterThan(value) {
+ const number = stringToNumber(value);
+ return {
+ required: ['depth'],
+ properties: {
+ depth: {type: 'number', exclusiveMinimum: number}
+ }
+ };
+}
- // url schema creation functions
+/**
+ * @param {string} value
+ * @returns {import('ext/json-schema').Schema}
+ */
+function createSchemaPopupLevelLessThanOrEqual(value) {
+ const number = stringToNumber(value);
+ return {
+ required: ['depth'],
+ properties: {
+ depth: {type: 'number', maximum: number}
+ }
+ };
+}
- /**
- * @param {string} value
- * @returns {import('ext/json-schema').Schema}
- */
- _createSchemaUrlMatchDomain(value) {
- const oneOf = [];
- for (let domain of this._split(value)) {
- if (domain.length === 0) { continue; }
- domain = domain.toLowerCase();
- oneOf.push({const: domain});
+/**
+ * @param {string} value
+ * @returns {import('ext/json-schema').Schema}
+ */
+function createSchemaPopupLevelGreaterThanOrEqual(value) {
+ const number = stringToNumber(value);
+ return {
+ required: ['depth'],
+ properties: {
+ depth: {type: 'number', minimum: number}
}
- return {
- required: ['domain'],
- properties: {
- domain: {oneOf}
- }
- };
- }
+ };
+}
- /**
- * @param {string} value
- * @returns {import('ext/json-schema').Schema}
- */
- _createSchemaUrlMatchRegExp(value) {
- return {
- required: ['url'],
- properties: {
- url: {type: 'string', pattern: value, patternFlags: 'i'}
- }
- };
+// url schema creation functions
+
+/**
+ * @param {string} value
+ * @returns {import('ext/json-schema').Schema}
+ */
+function createSchemaUrlMatchDomain(value) {
+ const oneOf = [];
+ for (let domain of split(value)) {
+ if (domain.length === 0) { continue; }
+ domain = domain.toLowerCase();
+ oneOf.push({const: domain});
}
+ return {
+ required: ['domain'],
+ properties: {
+ domain: {oneOf}
+ }
+ };
+}
- // modifierKeys schema creation functions
+/**
+ * @param {string} value
+ * @returns {import('ext/json-schema').Schema}
+ */
+function createSchemaUrlMatchRegExp(value) {
+ return {
+ required: ['url'],
+ properties: {
+ url: {type: 'string', pattern: value, patternFlags: 'i'}
+ }
+ };
+}
- /**
- * @param {string} value
- * @returns {import('ext/json-schema').Schema}
- */
- _createSchemaModifierKeysAre(value) {
- return this._createSchemaArrayCheck('modifierKeys', value, true, false);
- }
+// modifierKeys schema creation functions
- /**
- * @param {string} value
- * @returns {import('ext/json-schema').Schema}
- */
- _createSchemaModifierKeysAreNot(value) {
- return {
- not: {
- anyOf: [this._createSchemaArrayCheck('modifierKeys', value, true, false)]
- }
- };
- }
+/**
+ * @param {string} value
+ * @returns {import('ext/json-schema').Schema}
+ */
+function createSchemaModifierKeysAre(value) {
+ return createSchemaArrayCheck('modifierKeys', value, true, false);
+}
- /**
- * @param {string} value
- * @returns {import('ext/json-schema').Schema}
- */
- _createSchemaModifierKeysInclude(value) {
- return this._createSchemaArrayCheck('modifierKeys', value, false, false);
- }
+/**
+ * @param {string} value
+ * @returns {import('ext/json-schema').Schema}
+ */
+function createSchemaModifierKeysAreNot(value) {
+ return {
+ not: {
+ anyOf: [createSchemaArrayCheck('modifierKeys', value, true, false)]
+ }
+ };
+}
- /**
- * @param {string} value
- * @returns {import('ext/json-schema').Schema}
- */
- _createSchemaModifierKeysNotInclude(value) {
- return this._createSchemaArrayCheck('modifierKeys', value, false, true);
- }
+/**
+ * @param {string} value
+ * @returns {import('ext/json-schema').Schema}
+ */
+function createSchemaModifierKeysInclude(value) {
+ return createSchemaArrayCheck('modifierKeys', value, false, false);
+}
- // modifierKeys schema creation functions
+/**
+ * @param {string} value
+ * @returns {import('ext/json-schema').Schema}
+ */
+function createSchemaModifierKeysNotInclude(value) {
+ return createSchemaArrayCheck('modifierKeys', value, false, true);
+}
- /**
- * @param {string} value
- * @returns {import('ext/json-schema').Schema}
- */
- _createSchemaFlagsAre(value) {
- return this._createSchemaArrayCheck('flags', value, true, false);
- }
+// modifierKeys schema creation functions
- /**
- * @param {string} value
- * @returns {import('ext/json-schema').Schema}
- */
- _createSchemaFlagsAreNot(value) {
- return {
- not: {
- anyOf: [this._createSchemaArrayCheck('flags', value, true, false)]
- }
- };
- }
+/**
+ * @param {string} value
+ * @returns {import('ext/json-schema').Schema}
+ */
+function createSchemaFlagsAre(value) {
+ return createSchemaArrayCheck('flags', value, true, false);
+}
- /**
- * @param {string} value
- * @returns {import('ext/json-schema').Schema}
- */
- _createSchemaFlagsInclude(value) {
- return this._createSchemaArrayCheck('flags', value, false, false);
- }
+/**
+ * @param {string} value
+ * @returns {import('ext/json-schema').Schema}
+ */
+function createSchemaFlagsAreNot(value) {
+ return {
+ not: {
+ anyOf: [createSchemaArrayCheck('flags', value, true, false)]
+ }
+ };
+}
- /**
- * @param {string} value
- * @returns {import('ext/json-schema').Schema}
- */
- _createSchemaFlagsNotInclude(value) {
- return this._createSchemaArrayCheck('flags', value, false, true);
- }
+/**
+ * @param {string} value
+ * @returns {import('ext/json-schema').Schema}
+ */
+function createSchemaFlagsInclude(value) {
+ return createSchemaArrayCheck('flags', value, false, false);
+}
- // Generic
+/**
+ * @param {string} value
+ * @returns {import('ext/json-schema').Schema}
+ */
+function createSchemaFlagsNotInclude(value) {
+ return createSchemaArrayCheck('flags', value, false, true);
+}
- /**
- * @param {string} key
- * @param {string} value
- * @param {boolean} exact
- * @param {boolean} none
- * @returns {import('ext/json-schema').Schema}
- */
- _createSchemaArrayCheck(key, value, exact, none) {
- /** @type {import('ext/json-schema').Schema[]} */
- const containsList = [];
- for (const item of this._split(value)) {
- if (item.length === 0) { continue; }
- containsList.push({
- contains: {
- const: item
- }
- });
- }
- const containsListCount = containsList.length;
- /** @type {import('ext/json-schema').Schema} */
- const schema = {
- type: 'array'
- };
- if (exact) {
- schema.maxItems = containsListCount;
- }
- if (none) {
- if (containsListCount > 0) {
- schema.not = {anyOf: containsList};
- }
- } else {
- schema.minItems = containsListCount;
- if (containsListCount > 0) {
- schema.allOf = containsList;
+// Generic
+
+/**
+ * @param {string} key
+ * @param {string} value
+ * @param {boolean} exact
+ * @param {boolean} none
+ * @returns {import('ext/json-schema').Schema}
+ */
+function createSchemaArrayCheck(key, value, exact, none) {
+ /** @type {import('ext/json-schema').Schema[]} */
+ const containsList = [];
+ for (const item of split(value)) {
+ if (item.length === 0) { continue; }
+ containsList.push({
+ contains: {
+ const: item
}
+ });
+ }
+ const containsListCount = containsList.length;
+ /** @type {import('ext/json-schema').Schema} */
+ const schema = {
+ type: 'array'
+ };
+ if (exact) {
+ schema.maxItems = containsListCount;
+ }
+ if (none) {
+ if (containsListCount > 0) {
+ schema.not = {anyOf: containsList};
+ }
+ } else {
+ schema.minItems = containsListCount;
+ if (containsListCount > 0) {
+ schema.allOf = containsList;
}
- return {
- required: [key],
- properties: {
- [key]: schema
- }
- };
}
+ return {
+ required: [key],
+ properties: {
+ [key]: schema
+ }
+ };
}