summaryrefslogtreecommitdiff
path: root/ext/js
diff options
context:
space:
mode:
Diffstat (limited to 'ext/js')
-rw-r--r--ext/js/app/frontend.js13
-rw-r--r--ext/js/background/backend.js15
-rw-r--r--ext/js/data/options-util.js11
-rw-r--r--ext/js/language/text-scanner.js11
4 files changed, 44 insertions, 6 deletions
diff --git a/ext/js/app/frontend.js b/ext/js/app/frontend.js
index 39176475..bdb8cfc5 100644
--- a/ext/js/app/frontend.js
+++ b/ext/js/app/frontend.js
@@ -115,6 +115,7 @@ export class Frontend {
['frontendRequestReadyBroadcast', this._onMessageRequestFrontendReadyBroadcast.bind(this)],
['frontendSetAllVisibleOverride', this._onApiSetAllVisibleOverride.bind(this)],
['frontendClearAllVisibleOverride', this._onApiClearAllVisibleOverride.bind(this)],
+ ['frontendScanSelectedText', this._onApiScanSelectedText.bind(this)],
]);
this._hotkeyHandler.registerActions([
@@ -263,6 +264,13 @@ export class Frontend {
/**
* @returns {void}
*/
+ _onApiScanSelectedText() {
+ void this._scanSelectedText(false, true, true);
+ }
+
+ /**
+ * @returns {void}
+ */
_onActionScanTextAtSelection() {
void this._scanSelectedText(false, false);
}
@@ -934,13 +942,14 @@ export class Frontend {
/**
* @param {boolean} allowEmptyRange
* @param {boolean} disallowExpandSelection
+ * @param {boolean} showEmpty show empty popup if no results are found
* @returns {Promise<boolean>}
*/
- async _scanSelectedText(allowEmptyRange, disallowExpandSelection) {
+ async _scanSelectedText(allowEmptyRange, disallowExpandSelection, showEmpty = false) {
const range = this._getFirstSelectionRange(allowEmptyRange);
if (range === null) { return false; }
const source = disallowExpandSelection ? TextSourceRange.createLazy(range) : TextSourceRange.create(range);
- await this._textScanner.search(source, {focus: true, restoreSelection: true});
+ await this._textScanner.search(source, {focus: true, restoreSelection: true}, showEmpty);
return true;
}
diff --git a/ext/js/background/backend.js b/ext/js/background/backend.js
index a04566c9..88912b70 100644
--- a/ext/js/background/backend.js
+++ b/ext/js/background/backend.js
@@ -1310,6 +1310,21 @@ export class Backend {
this._clipboardMonitor.stop();
}
+ if (options.general.enableContextMenuScanSelected) {
+ chrome.contextMenus.create({
+ id: 'yomitan_lookup',
+ title: 'Lookup in Yomitan',
+ contexts: ['selection'],
+ });
+ chrome.contextMenus.onClicked.addListener((info) => {
+ if (info.selectionText) {
+ this._sendMessageAllTabsIgnoreResponse({action: 'frontendScanSelectedText'});
+ }
+ });
+ } else {
+ chrome.contextMenus.remove('yomitan_lookup', () => this._checkLastError(chrome.runtime.lastError));
+ }
+
void this._accessibilityController.update(this._getOptionsFull(false));
this._sendMessageAllTabsIgnoreResponse({action: 'applicationOptionsUpdated', params: {source}});
diff --git a/ext/js/data/options-util.js b/ext/js/data/options-util.js
index 5ef30adb..c6bdf025 100644
--- a/ext/js/data/options-util.js
+++ b/ext/js/data/options-util.js
@@ -546,6 +546,7 @@ export class OptionsUtil {
this._updateVersion36,
this._updateVersion37,
this._updateVersion38,
+ this._updateVersion39,
];
/* eslint-enable @typescript-eslint/unbound-method */
if (typeof targetVersion === 'number' && targetVersion < result.length) {
@@ -1314,6 +1315,16 @@ export class OptionsUtil {
}
/**
+ * - Add new setting enableContextMenuScanSelected
+ * @type {import('options-util').UpdateFunction}
+ */
+ async _updateVersion39(options) {
+ for (const profile of options.profiles) {
+ profile.options.general.enableContextMenuScanSelected = true;
+ }
+ }
+
+ /**
* @param {string} url
* @returns {Promise<chrome.tabs.Tab>}
*/
diff --git a/ext/js/language/text-scanner.js b/ext/js/language/text-scanner.js
index aba44644..fdc33400 100644
--- a/ext/js/language/text-scanner.js
+++ b/ext/js/language/text-scanner.js
@@ -411,10 +411,11 @@ export class TextScanner extends EventDispatcher {
/**
* @param {import('text-source').TextSource} textSource
* @param {import('text-scanner').InputInfoDetail} [inputDetail]
+ * @param {boolean} showEmpty
*/
- async search(textSource, inputDetail) {
+ async search(textSource, inputDetail, showEmpty = false) {
const inputInfo = this._createInputInfo(null, 'script', 'script', true, [], [], inputDetail);
- await this._search(textSource, this._searchTerms, this._searchKanji, inputInfo);
+ await this._search(textSource, this._searchTerms, this._searchKanji, inputInfo, showEmpty);
}
// Private
@@ -437,8 +438,9 @@ export class TextScanner extends EventDispatcher {
* @param {boolean} searchTerms
* @param {boolean} searchKanji
* @param {import('text-scanner').InputInfo} inputInfo
+ * @param {boolean} showEmpty shows a "No results found" popup if no results are found
*/
- async _search(textSource, searchTerms, searchKanji, inputInfo) {
+ async _search(textSource, searchTerms, searchKanji, inputInfo, showEmpty = false) {
try {
const inputInfoDetail = inputInfo.detail;
const selectionRestoreInfo = (
@@ -465,7 +467,8 @@ export class TextScanner extends EventDispatcher {
const result = await this._findDictionaryEntries(textSource, searchTerms, searchKanji, optionsContext);
if (result !== null) {
({dictionaryEntries, sentence, type} = result);
- } else if (textSource !== null && textSource instanceof TextSourceElement && await this._isTextLookupWorthy(textSource.fullContent)) {
+ } else if (showEmpty || (textSource !== null && textSource instanceof TextSourceElement && await this._isTextLookupWorthy(textSource.fullContent))) {
+ // Shows a "No results found" message
dictionaryEntries = [];
sentence = {text: '', offset: 0};
}