diff options
author | toasted-nutbread <toasted-nutbread@users.noreply.github.com> | 2021-05-01 15:54:31 -0400 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-05-01 15:54:31 -0400 |
commit | c514bbc4fbe39f611d7d9cfd3a48681bacbaf559 (patch) | |
tree | 275c792977b0c925fca67a324b036e1a81ba25dc /ext/js | |
parent | 8bf6ff92f9e318554139d3f21f1dcdb98ce59036 (diff) |
Flags profile conditions (#1647)
* Generalize modifier keys
* Optimize bindings
* Add support for flags
* Add clipboard flag
* Update tests
* Add tests
Diffstat (limited to 'ext/js')
-rw-r--r-- | ext/js/background/profile-conditions-util.js | 67 | ||||
-rw-r--r-- | ext/js/display/search-display-controller.js | 14 | ||||
-rw-r--r-- | ext/js/pages/settings/profile-conditions-ui.js | 46 |
3 files changed, 101 insertions, 26 deletions
diff --git a/ext/js/background/profile-conditions-util.js b/ext/js/background/profile-conditions-util.js index 928026e0..dcd60796 100644 --- a/ext/js/background/profile-conditions-util.js +++ b/ext/js/background/profile-conditions-util.js @@ -57,6 +57,17 @@ class ProfileConditionsUtil { ['notInclude', this._createSchemaModifierKeysNotInclude.bind(this)] ]) } + ], + [ + 'flags', + { + operators: new Map([ + ['are', this._createSchemaFlagsAre.bind(this)], + ['areNot', this._createSchemaFlagsAreNot.bind(this)], + ['include', this._createSchemaFlagsInclude.bind(this)], + ['notInclude', this._createSchemaFlagsNotInclude.bind(this)] + ]) + } ] ]); } @@ -121,6 +132,10 @@ class ProfileConditionsUtil { // NOP } } + const {flags} = normalizedContext; + if (!Array.isArray(flags)) { + normalizedContext.flags = []; + } return normalizedContext; } @@ -222,54 +237,76 @@ class ProfileConditionsUtil { // modifierKeys schema creation functions _createSchemaModifierKeysAre(value) { - return this._createSchemaModifierKeysGeneric(value, true, false); + return this._createSchemaArrayCheck('modifierKeys', value, true, false); } _createSchemaModifierKeysAreNot(value) { return { - not: [this._createSchemaModifierKeysGeneric(value, true, false)] + not: [this._createSchemaArrayCheck('modifierKeys', value, true, false)] }; } _createSchemaModifierKeysInclude(value) { - return this._createSchemaModifierKeysGeneric(value, false, false); + return this._createSchemaArrayCheck('modifierKeys', value, false, false); } _createSchemaModifierKeysNotInclude(value) { - return this._createSchemaModifierKeysGeneric(value, false, true); + return this._createSchemaArrayCheck('modifierKeys', value, false, true); + } + + // modifierKeys schema creation functions + + _createSchemaFlagsAre(value) { + return this._createSchemaArrayCheck('flags', value, true, false); + } + + _createSchemaFlagsAreNot(value) { + return { + not: [this._createSchemaArrayCheck('flags', value, true, false)] + }; } - _createSchemaModifierKeysGeneric(value, exact, none) { + _createSchemaFlagsInclude(value) { + return this._createSchemaArrayCheck('flags', value, false, false); + } + + _createSchemaFlagsNotInclude(value) { + return this._createSchemaArrayCheck('flags', value, false, true); + } + + // Generic + + _createSchemaArrayCheck(key, value, exact, none) { const containsList = []; - for (const modifierKey of this._split(value)) { - if (modifierKey.length === 0) { continue; } + for (const item of this._split(value)) { + if (item.length === 0) { continue; } containsList.push({ contains: { - const: modifierKey + const: item } }); } const containsListCount = containsList.length; - const modifierKeysSchema = { + const schema = { type: 'array' }; if (exact) { - modifierKeysSchema.maxItems = containsListCount; + schema.maxItems = containsListCount; } if (none) { if (containsListCount > 0) { - modifierKeysSchema.not = containsList; + schema.not = containsList; } } else { - modifierKeysSchema.minItems = containsListCount; + schema.minItems = containsListCount; if (containsListCount > 0) { - modifierKeysSchema.allOf = containsList; + schema.allOf = containsList; } } return { - required: ['modifierKeys'], + required: [key], properties: { - modifierKeys: modifierKeysSchema + [key]: schema } }; } diff --git a/ext/js/display/search-display-controller.js b/ext/js/display/search-display-controller.js index f672909e..e60de796 100644 --- a/ext/js/display/search-display-controller.js +++ b/ext/js/display/search-display-controller.js @@ -179,12 +179,12 @@ class SearchDisplayController { e.preventDefault(); e.stopImmediatePropagation(); this._display.blurElement(e.currentTarget); - this._search(true, true, true); + this._search(true, true, true, null); } _onSearch(e) { e.preventDefault(); - this._search(true, true, true); + this._search(true, true, true, null); } _onCopy() { @@ -199,7 +199,7 @@ class SearchDisplayController { } this._queryInput.value = text; this._updateSearchHeight(true); - this._search(animate, false, autoSearchContent); + this._search(animate, false, autoSearchContent, ['clipboard']); } _onWanakanaEnableChange(e) { @@ -342,11 +342,15 @@ class SearchDisplayController { }); } - _search(animate, history, lookup) { + _search(animate, history, lookup, flags) { const query = this._queryInput.value; const depth = this._display.depth; const url = window.location.href; const documentTitle = document.title; + const optionsContext = {depth, url}; + if (flags !== null) { + optionsContext.flags = flags; + } const details = { focus: false, history, @@ -355,7 +359,7 @@ class SearchDisplayController { }, state: { focusEntry: 0, - optionsContext: {depth, url}, + optionsContext, url, sentence: {text: query, offset: 0}, documentTitle diff --git a/ext/js/pages/settings/profile-conditions-ui.js b/ext/js/pages/settings/profile-conditions-ui.js index 5fda1dc0..0a598693 100644 --- a/ext/js/pages/settings/profile-conditions-ui.js +++ b/ext/js/pages/settings/profile-conditions-ui.js @@ -30,6 +30,10 @@ class ProfileConditionsUI extends EventDispatcher { this._eventListeners = new EventListenerCollection(); this._defaultType = 'popupLevel'; this._profileIndex = 0; + const validateInteger = this._validateInteger.bind(this); + const normalizeInteger = this._normalizeInteger.bind(this); + const validateFlags = this._validateFlags.bind(this); + const normalizeFlags = this._normalizeFlags.bind(this); this._descriptors = new Map([ [ 'popupLevel', @@ -37,12 +41,12 @@ class ProfileConditionsUI extends EventDispatcher { displayName: 'Popup Level', defaultOperator: 'equal', operators: new Map([ - ['equal', {displayName: '=', type: 'integer', defaultValue: '0', validate: this._validateInteger.bind(this), normalize: this._normalizeInteger.bind(this)}], - ['notEqual', {displayName: '\u2260', type: 'integer', defaultValue: '0', validate: this._validateInteger.bind(this), normalize: this._normalizeInteger.bind(this)}], - ['lessThan', {displayName: '<', type: 'integer', defaultValue: '0', validate: this._validateInteger.bind(this), normalize: this._normalizeInteger.bind(this)}], - ['greaterThan', {displayName: '>', type: 'integer', defaultValue: '0', validate: this._validateInteger.bind(this), normalize: this._normalizeInteger.bind(this)}], - ['lessThanOrEqual', {displayName: '\u2264', type: 'integer', defaultValue: '0', validate: this._validateInteger.bind(this), normalize: this._normalizeInteger.bind(this)}], - ['greaterThanOrEqual', {displayName: '\u2265', type: 'integer', defaultValue: '0', validate: this._validateInteger.bind(this), normalize: this._normalizeInteger.bind(this)}] + ['equal', {displayName: '=', type: 'integer', defaultValue: '0', validate: validateInteger, normalize: normalizeInteger}], + ['notEqual', {displayName: '\u2260', type: 'integer', defaultValue: '0', validate: validateInteger, normalize: normalizeInteger}], + ['lessThan', {displayName: '<', type: 'integer', defaultValue: '0', validate: validateInteger, normalize: normalizeInteger}], + ['greaterThan', {displayName: '>', type: 'integer', defaultValue: '0', validate: validateInteger, normalize: normalizeInteger}], + ['lessThanOrEqual', {displayName: '\u2264', type: 'integer', defaultValue: '0', validate: validateInteger, normalize: normalizeInteger}], + ['greaterThanOrEqual', {displayName: '\u2265', type: 'integer', defaultValue: '0', validate: validateInteger, normalize: normalizeInteger}] ]) } ], @@ -69,8 +73,24 @@ class ProfileConditionsUI extends EventDispatcher { ['notInclude', {displayName: 'Don\'t Include', type: 'modifierKeys', defaultValue: ''}] ]) } + ], + [ + 'flags', + { + displayName: 'Flags', + defaultOperator: 'are', + operators: new Map([ + ['are', {displayName: 'Are', type: 'string', defaultValue: '', validate: validateFlags, normalize: normalizeFlags}], + ['areNot', {displayName: 'Are Not', type: 'string', defaultValue: '', validate: validateFlags, normalize: normalizeFlags}], + ['include', {displayName: 'Include', type: 'string', defaultValue: '', validate: validateFlags, normalize: normalizeFlags}], + ['notInclude', {displayName: 'Don\'t Include', type: 'string', defaultValue: '', validate: validateFlags, normalize: normalizeFlags}] + ]) + } ] ]); + this._validFlags = new Set([ + 'clipboard' + ]); } get settingsController() { @@ -280,6 +300,20 @@ class ProfileConditionsUI extends EventDispatcher { return this.splitValue(value).join(', '); } + _validateFlags(value) { + const flags = this.splitValue(value); + for (const flag of flags) { + if (!this._validFlags.has(flag)) { + return false; + } + } + return flags.length > 0; + } + + _normalizeFlags(value) { + return [...new Set(this.splitValue(value))].join(', '); + } + _triggerConditionGroupCountChanged(count) { this.trigger('conditionGroupCountChanged', {count, profileIndex: this._profileIndex}); } |