Mecab test (#1361)
* Update Mecab API * Add testMecab API function * Add a test button for the Mecab component
This commit is contained in:
parent
0ed24347ee
commit
0f5fb804d0
@ -122,7 +122,8 @@ class Backend {
|
|||||||
['setAllSettings', {async: true, contentScript: false, handler: this._onApiSetAllSettings.bind(this)}],
|
['setAllSettings', {async: true, contentScript: false, handler: this._onApiSetAllSettings.bind(this)}],
|
||||||
['getOrCreateSearchPopup', {async: true, contentScript: true, handler: this._onApiGetOrCreateSearchPopup.bind(this)}],
|
['getOrCreateSearchPopup', {async: true, contentScript: true, handler: this._onApiGetOrCreateSearchPopup.bind(this)}],
|
||||||
['isTabSearchPopup', {async: true, contentScript: true, handler: this._onApiIsTabSearchPopup.bind(this)}],
|
['isTabSearchPopup', {async: true, contentScript: true, handler: this._onApiIsTabSearchPopup.bind(this)}],
|
||||||
['triggerDatabaseUpdated', {async: false, contentScript: true, handler: this._onApiTriggerDatabaseUpdated.bind(this)}]
|
['triggerDatabaseUpdated', {async: false, contentScript: true, handler: this._onApiTriggerDatabaseUpdated.bind(this)}],
|
||||||
|
['testMecab', {async: true, contentScript: true, handler: this._onApiTestMecab.bind(this)}]
|
||||||
]);
|
]);
|
||||||
this._messageHandlersWithProgress = new Map([
|
this._messageHandlersWithProgress = new Map([
|
||||||
]);
|
]);
|
||||||
@ -676,6 +677,42 @@ class Backend {
|
|||||||
this._triggerDatabaseUpdated(type, cause);
|
this._triggerDatabaseUpdated(type, cause);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async _onApiTestMecab() {
|
||||||
|
if (!this._mecab.isEnabled()) {
|
||||||
|
throw new Error('MeCab not enabled');
|
||||||
|
}
|
||||||
|
|
||||||
|
let permissionsOkay = false;
|
||||||
|
try {
|
||||||
|
permissionsOkay = await this._hasPermissions({permissions: ['nativeMessaging']});
|
||||||
|
} catch (e) {
|
||||||
|
// NOP
|
||||||
|
}
|
||||||
|
if (!permissionsOkay) {
|
||||||
|
throw new Error('Insufficient permissions');
|
||||||
|
}
|
||||||
|
|
||||||
|
const disconnect = !this._mecab.isConnected();
|
||||||
|
try {
|
||||||
|
const version = await this._mecab.getVersion();
|
||||||
|
if (version === null) {
|
||||||
|
throw new Error('Could not connect to native MeCab component');
|
||||||
|
}
|
||||||
|
|
||||||
|
const localVersion = this._mecab.getLocalVersion();
|
||||||
|
if (version !== localVersion) {
|
||||||
|
throw new Error(`MeCab component version not supported: ${version}`);
|
||||||
|
}
|
||||||
|
} finally {
|
||||||
|
// Disconnect if the connection was previously disconnected
|
||||||
|
if (disconnect && this._mecab.isEnabled() && this._mecab.isActive()) {
|
||||||
|
this._mecab.disconnect();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
// Command handlers
|
// Command handlers
|
||||||
|
|
||||||
async _onCommandOpenSearchPage(params) {
|
async _onCommandOpenSearchPage(params) {
|
||||||
@ -1904,4 +1941,15 @@ class Backend {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_hasPermissions(permissions) {
|
||||||
|
return new Promise((resolve, reject) => chrome.permissions.contains(permissions, (result) => {
|
||||||
|
const e = chrome.runtime.lastError;
|
||||||
|
if (e) {
|
||||||
|
reject(new Error(e.message));
|
||||||
|
} else {
|
||||||
|
resolve(result);
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -53,6 +53,39 @@ class Mecab {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Disconnects the current port, but does not disable future connections.
|
||||||
|
*/
|
||||||
|
disconnect() {
|
||||||
|
if (this._port !== null) {
|
||||||
|
this._clearPort();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns whether or not the connection to the native application is active.
|
||||||
|
* @returns `true` if the connection is active, `false` otherwise.
|
||||||
|
*/
|
||||||
|
isConnected() {
|
||||||
|
return (this._port !== null);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns whether or not any invocation is currently active.
|
||||||
|
* @returns `true` if an invocation is active, `false` otherwise.
|
||||||
|
*/
|
||||||
|
isActive() {
|
||||||
|
return (this._invocations.size > 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the local API version being used.
|
||||||
|
* @returns An integer representing the API version that Yomichan uses.
|
||||||
|
*/
|
||||||
|
getLocalVersion() {
|
||||||
|
return this._version;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the version of the MeCab component.
|
* Gets the version of the MeCab component.
|
||||||
* @returns The version of the MeCab component, or `null` if the component was not found.
|
* @returns The version of the MeCab component, or `null` if the component was not found.
|
||||||
|
67
ext/bg/js/settings2/mecab-controller.js
Normal file
67
ext/bg/js/settings2/mecab-controller.js
Normal file
@ -0,0 +1,67 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2021 Yomichan Authors
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* global
|
||||||
|
* api
|
||||||
|
*/
|
||||||
|
|
||||||
|
class MecabController {
|
||||||
|
constructor(settingsController) {
|
||||||
|
this._settingsController = settingsController;
|
||||||
|
this._testButton = null;
|
||||||
|
this._resultsContainer = null;
|
||||||
|
this._testActive = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
prepare() {
|
||||||
|
this._testButton = document.querySelector('#test-mecab-button');
|
||||||
|
this._resultsContainer = document.querySelector('#test-mecab-results');
|
||||||
|
|
||||||
|
this._testButton.addEventListener('click', this._onTestButtonClick.bind(this), false);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Private
|
||||||
|
|
||||||
|
_onTestButtonClick(e) {
|
||||||
|
e.preventDefault();
|
||||||
|
this._testMecab();
|
||||||
|
}
|
||||||
|
|
||||||
|
async _testMecab() {
|
||||||
|
if (this._testActive) { return; }
|
||||||
|
|
||||||
|
try {
|
||||||
|
this._testActive = true;
|
||||||
|
this._testButton.disabled = true;
|
||||||
|
this._resultsContainer.textContent = '';
|
||||||
|
this._resultsContainer.hidden = true;
|
||||||
|
await api.testMecab();
|
||||||
|
this._setStatus('Connection was successful', false);
|
||||||
|
} catch (e) {
|
||||||
|
this._setStatus(e.message, true);
|
||||||
|
} finally {
|
||||||
|
this._testActive = false;
|
||||||
|
this._testButton.disabled = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_setStatus(message, isError) {
|
||||||
|
this._resultsContainer.textContent = message;
|
||||||
|
this._resultsContainer.hidden = false;
|
||||||
|
this._resultsContainer.classList.toggle('danger-text', isError);
|
||||||
|
}
|
||||||
|
}
|
@ -26,6 +26,7 @@
|
|||||||
* ExtensionKeyboardShortcutController
|
* ExtensionKeyboardShortcutController
|
||||||
* GenericSettingController
|
* GenericSettingController
|
||||||
* KeyboardShortcutController
|
* KeyboardShortcutController
|
||||||
|
* MecabController
|
||||||
* ModalController
|
* ModalController
|
||||||
* NestedPopupsController
|
* NestedPopupsController
|
||||||
* PermissionsToggleController
|
* PermissionsToggleController
|
||||||
@ -140,6 +141,9 @@ async function setupGenericSettingsController(genericSettingController) {
|
|||||||
const popupWindowController = new PopupWindowController();
|
const popupWindowController = new PopupWindowController();
|
||||||
popupWindowController.prepare();
|
popupWindowController.prepare();
|
||||||
|
|
||||||
|
const mecabController = new MecabController();
|
||||||
|
mecabController.prepare();
|
||||||
|
|
||||||
await Promise.all(preparePromises);
|
await Promise.all(preparePromises);
|
||||||
|
|
||||||
document.documentElement.dataset.loaded = 'true';
|
document.documentElement.dataset.loaded = 'true';
|
||||||
|
@ -1166,7 +1166,11 @@
|
|||||||
In order for Yomichan to use it, both MeCab and a native messaging component must be installed.
|
In order for Yomichan to use it, both MeCab and a native messaging component must be installed.
|
||||||
A setup guide can be found <a href="https://github.com/siikamiika/yomichan-mecab-installer/blob/master/README.md" target="_blank" rel="noopener noreferrer">here</a>.
|
A setup guide can be found <a href="https://github.com/siikamiika/yomichan-mecab-installer/blob/master/README.md" target="_blank" rel="noopener noreferrer">here</a>.
|
||||||
</p>
|
</p>
|
||||||
<p>
|
<div class="margin-above flex-row-nowrap">
|
||||||
|
<button id="test-mecab-button">Test</button>
|
||||||
|
<div id="test-mecab-results" class="flex-margin-left" hidden></div>
|
||||||
|
</div>
|
||||||
|
<p class="margin-above">
|
||||||
<a class="more-toggle" data-parent-distance="3">Less…</a>
|
<a class="more-toggle" data-parent-distance="3">Less…</a>
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
@ -3241,6 +3245,7 @@
|
|||||||
|
|
||||||
<script src="/bg/js/settings2/extension-keyboard-shortcuts-controller.js"></script>
|
<script src="/bg/js/settings2/extension-keyboard-shortcuts-controller.js"></script>
|
||||||
<script src="/bg/js/settings2/keyboard-shortcuts-controller.js"></script>
|
<script src="/bg/js/settings2/keyboard-shortcuts-controller.js"></script>
|
||||||
|
<script src="/bg/js/settings2/mecab-controller.js"></script>
|
||||||
<script src="/bg/js/settings2/nested-popups-controller.js"></script>
|
<script src="/bg/js/settings2/nested-popups-controller.js"></script>
|
||||||
<script src="/bg/js/settings2/popup-window-controller.js"></script>
|
<script src="/bg/js/settings2/popup-window-controller.js"></script>
|
||||||
<script src="/bg/js/settings2/secondary-search-dictionary-controller.js"></script>
|
<script src="/bg/js/settings2/secondary-search-dictionary-controller.js"></script>
|
||||||
|
@ -193,6 +193,10 @@ const api = (() => {
|
|||||||
return this._invoke('triggerDatabaseUpdated', {type, cause});
|
return this._invoke('triggerDatabaseUpdated', {type, cause});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
testMecab() {
|
||||||
|
return this._invoke('testMecab', {});
|
||||||
|
}
|
||||||
|
|
||||||
// Utilities
|
// Utilities
|
||||||
|
|
||||||
_createActionPort(timeout=5000) {
|
_createActionPort(timeout=5000) {
|
||||||
|
Loading…
Reference in New Issue
Block a user