Error logging refactoring (#454)
* Create new logging methods on yomichan object * Use new yomichan.logError instead of global logError * Remove old logError * Handle unhandledrejection events * Add addEventListener stub * Update log function * Update error conversion to support more types * Add log event * Add API log function * Log errors to the backend * Make error/warning logs update the badge * Clear log error indicator on extension button click * Log correct URL on the background page * Fix incorrect error conversion * Remove unhandledrejection handling Firefox doesn't support it properly. * Remove unused argument type from log function * Improve function name * Change console.warn to yomichan.logWarning * Move log forwarding initialization into main scripts
This commit is contained in:
parent
ca033a87a0
commit
5b96559df8
@ -80,7 +80,6 @@
|
|||||||
"yomichan": "readonly",
|
"yomichan": "readonly",
|
||||||
"errorToJson": "readonly",
|
"errorToJson": "readonly",
|
||||||
"jsonToError": "readonly",
|
"jsonToError": "readonly",
|
||||||
"logError": "readonly",
|
|
||||||
"isObject": "readonly",
|
"isObject": "readonly",
|
||||||
"hasOwn": "readonly",
|
"hasOwn": "readonly",
|
||||||
"toIterable": "readonly",
|
"toIterable": "readonly",
|
||||||
|
@ -78,6 +78,7 @@ class Backend {
|
|||||||
this._isPrepared = false;
|
this._isPrepared = false;
|
||||||
this._prepareError = false;
|
this._prepareError = false;
|
||||||
this._badgePrepareDelayTimer = null;
|
this._badgePrepareDelayTimer = null;
|
||||||
|
this._logErrorLevel = null;
|
||||||
|
|
||||||
this._messageHandlers = new Map([
|
this._messageHandlers = new Map([
|
||||||
['yomichanCoreReady', {handler: this._onApiYomichanCoreReady.bind(this), async: false}],
|
['yomichanCoreReady', {handler: this._onApiYomichanCoreReady.bind(this), async: false}],
|
||||||
@ -112,7 +113,9 @@ class Backend {
|
|||||||
['getDictionaryInfo', {handler: this._onApiGetDictionaryInfo.bind(this), async: true}],
|
['getDictionaryInfo', {handler: this._onApiGetDictionaryInfo.bind(this), async: true}],
|
||||||
['getDictionaryCounts', {handler: this._onApiGetDictionaryCounts.bind(this), async: true}],
|
['getDictionaryCounts', {handler: this._onApiGetDictionaryCounts.bind(this), async: true}],
|
||||||
['purgeDatabase', {handler: this._onApiPurgeDatabase.bind(this), async: true}],
|
['purgeDatabase', {handler: this._onApiPurgeDatabase.bind(this), async: true}],
|
||||||
['getMedia', {handler: this._onApiGetMedia.bind(this), async: true}]
|
['getMedia', {handler: this._onApiGetMedia.bind(this), async: true}],
|
||||||
|
['log', {handler: this._onApiLog.bind(this), async: false}],
|
||||||
|
['logIndicatorClear', {handler: this._onApiLogIndicatorClear.bind(this), async: false}]
|
||||||
]);
|
]);
|
||||||
|
|
||||||
this._commandHandlers = new Map([
|
this._commandHandlers = new Map([
|
||||||
@ -164,7 +167,7 @@ class Backend {
|
|||||||
this._isPrepared = true;
|
this._isPrepared = true;
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
this._prepareError = true;
|
this._prepareError = true;
|
||||||
logError(e);
|
yomichan.logError(e);
|
||||||
throw e;
|
throw e;
|
||||||
} finally {
|
} finally {
|
||||||
if (this._badgePrepareDelayTimer !== null) {
|
if (this._badgePrepareDelayTimer !== null) {
|
||||||
@ -260,7 +263,7 @@ class Backend {
|
|||||||
this.options = JsonSchema.getValidValueOrDefault(this.optionsSchema, utilIsolate(options));
|
this.options = JsonSchema.getValidValueOrDefault(this.optionsSchema, utilIsolate(options));
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
// This shouldn't happen, but catch errors just in case of bugs
|
// This shouldn't happen, but catch errors just in case of bugs
|
||||||
logError(e);
|
yomichan.logError(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -767,8 +770,34 @@ class Backend {
|
|||||||
return await this.database.getMedia(targets);
|
return await this.database.getMedia(targets);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_onApiLog({error, level, context}) {
|
||||||
|
yomichan.log(jsonToError(error), level, context);
|
||||||
|
|
||||||
|
const levelValue = this._getErrorLevelValue(level);
|
||||||
|
if (levelValue <= this._getErrorLevelValue(this._logErrorLevel)) { return; }
|
||||||
|
|
||||||
|
this._logErrorLevel = level;
|
||||||
|
this._updateBadge();
|
||||||
|
}
|
||||||
|
|
||||||
|
_onApiLogIndicatorClear() {
|
||||||
|
if (this._logErrorLevel === null) { return; }
|
||||||
|
this._logErrorLevel = null;
|
||||||
|
this._updateBadge();
|
||||||
|
}
|
||||||
|
|
||||||
// Command handlers
|
// Command handlers
|
||||||
|
|
||||||
|
_getErrorLevelValue(errorLevel) {
|
||||||
|
switch (errorLevel) {
|
||||||
|
case 'info': return 0;
|
||||||
|
case 'debug': return 0;
|
||||||
|
case 'warn': return 1;
|
||||||
|
case 'error': return 2;
|
||||||
|
default: return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
async _onCommandSearch(params) {
|
async _onCommandSearch(params) {
|
||||||
const {mode='existingOrNewTab', query} = params || {};
|
const {mode='existingOrNewTab', query} = params || {};
|
||||||
|
|
||||||
@ -890,7 +919,20 @@ class Backend {
|
|||||||
let color = null;
|
let color = null;
|
||||||
let status = null;
|
let status = null;
|
||||||
|
|
||||||
if (!this._isPrepared) {
|
if (this._logErrorLevel !== null) {
|
||||||
|
switch (this._logErrorLevel) {
|
||||||
|
case 'error':
|
||||||
|
text = '!!';
|
||||||
|
color = '#f04e4e';
|
||||||
|
status = 'Error';
|
||||||
|
break;
|
||||||
|
default: // 'warn'
|
||||||
|
text = '!';
|
||||||
|
color = '#f0ad4e';
|
||||||
|
status = 'Warning';
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} else if (!this._isPrepared) {
|
||||||
if (this._prepareError) {
|
if (this._prepareError) {
|
||||||
text = '!!';
|
text = '!!';
|
||||||
color = '#f04e4e';
|
color = '#f04e4e';
|
||||||
|
@ -17,7 +17,9 @@
|
|||||||
|
|
||||||
/* global
|
/* global
|
||||||
* apiCommandExec
|
* apiCommandExec
|
||||||
|
* apiForwardLogsToBackend
|
||||||
* apiGetEnvironmentInfo
|
* apiGetEnvironmentInfo
|
||||||
|
* apiLogIndicatorClear
|
||||||
* apiOptionsGet
|
* apiOptionsGet
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@ -52,8 +54,11 @@ function setupButtonEvents(selector, command, url) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async function mainInner() {
|
async function mainInner() {
|
||||||
|
apiForwardLogsToBackend();
|
||||||
await yomichan.prepare();
|
await yomichan.prepare();
|
||||||
|
|
||||||
|
await apiLogIndicatorClear();
|
||||||
|
|
||||||
showExtensionInfo();
|
showExtensionInfo();
|
||||||
|
|
||||||
apiGetEnvironmentInfo().then(({browser}) => {
|
apiGetEnvironmentInfo().then(({browser}) => {
|
||||||
|
@ -104,7 +104,7 @@ class Database {
|
|||||||
});
|
});
|
||||||
return true;
|
return true;
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
logError(e);
|
yomichan.logError(e);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -24,7 +24,7 @@ class Mecab {
|
|||||||
}
|
}
|
||||||
|
|
||||||
onError(error) {
|
onError(error) {
|
||||||
logError(error, false);
|
yomichan.logError(error);
|
||||||
}
|
}
|
||||||
|
|
||||||
async checkVersion() {
|
async checkVersion() {
|
||||||
|
@ -17,6 +17,7 @@
|
|||||||
|
|
||||||
/* global
|
/* global
|
||||||
* DisplaySearch
|
* DisplaySearch
|
||||||
|
* apiForwardLogsToBackend
|
||||||
* apiOptionsGet
|
* apiOptionsGet
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@ -53,6 +54,7 @@ function injectSearchFrontend() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
(async () => {
|
(async () => {
|
||||||
|
apiForwardLogsToBackend();
|
||||||
await yomichan.prepare();
|
await yomichan.prepare();
|
||||||
|
|
||||||
const displaySearch = new DisplaySearch();
|
const displaySearch = new DisplaySearch();
|
||||||
|
@ -45,7 +45,7 @@ class QueryParser extends TextScanner {
|
|||||||
}
|
}
|
||||||
|
|
||||||
onError(error) {
|
onError(error) {
|
||||||
logError(error, false);
|
yomichan.logError(error);
|
||||||
}
|
}
|
||||||
|
|
||||||
onClick(e) {
|
onClick(e) {
|
||||||
|
@ -122,7 +122,7 @@ class DisplaySearch extends Display {
|
|||||||
}
|
}
|
||||||
|
|
||||||
onError(error) {
|
onError(error) {
|
||||||
logError(error, true);
|
yomichan.logError(error);
|
||||||
}
|
}
|
||||||
|
|
||||||
onSearchClear() {
|
onSearchClear() {
|
||||||
|
@ -133,7 +133,7 @@ async function _settingsImportSetOptionsFull(optionsFull) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function _showSettingsImportError(error) {
|
function _showSettingsImportError(error) {
|
||||||
logError(error);
|
yomichan.logError(error);
|
||||||
document.querySelector('#settings-import-error-modal-message').textContent = `${error}`;
|
document.querySelector('#settings-import-error-modal-message').textContent = `${error}`;
|
||||||
$('#settings-import-error-modal').modal('show');
|
$('#settings-import-error-modal').modal('show');
|
||||||
}
|
}
|
||||||
|
@ -554,7 +554,7 @@ function dictionaryErrorsShow(errors) {
|
|||||||
if (errors !== null && errors.length > 0) {
|
if (errors !== null && errors.length > 0) {
|
||||||
const uniqueErrors = new Map();
|
const uniqueErrors = new Map();
|
||||||
for (let e of errors) {
|
for (let e of errors) {
|
||||||
logError(e);
|
yomichan.logError(e);
|
||||||
e = dictionaryErrorToString(e);
|
e = dictionaryErrorToString(e);
|
||||||
let count = uniqueErrors.get(e);
|
let count = uniqueErrors.get(e);
|
||||||
if (typeof count === 'undefined') {
|
if (typeof count === 'undefined') {
|
||||||
|
@ -21,6 +21,7 @@
|
|||||||
* ankiInitialize
|
* ankiInitialize
|
||||||
* ankiTemplatesInitialize
|
* ankiTemplatesInitialize
|
||||||
* ankiTemplatesUpdateValue
|
* ankiTemplatesUpdateValue
|
||||||
|
* apiForwardLogsToBackend
|
||||||
* apiOptionsSave
|
* apiOptionsSave
|
||||||
* appearanceInitialize
|
* appearanceInitialize
|
||||||
* audioSettingsInitialize
|
* audioSettingsInitialize
|
||||||
@ -284,6 +285,7 @@ function showExtensionInformation() {
|
|||||||
|
|
||||||
|
|
||||||
async function onReady() {
|
async function onReady() {
|
||||||
|
apiForwardLogsToBackend();
|
||||||
await yomichan.prepare();
|
await yomichan.prepare();
|
||||||
|
|
||||||
showExtensionInformation();
|
showExtensionInformation();
|
||||||
|
@ -17,8 +17,10 @@
|
|||||||
|
|
||||||
/* global
|
/* global
|
||||||
* SettingsPopupPreview
|
* SettingsPopupPreview
|
||||||
|
* apiForwardLogsToBackend
|
||||||
*/
|
*/
|
||||||
|
|
||||||
(() => {
|
(() => {
|
||||||
|
apiForwardLogsToBackend();
|
||||||
new SettingsPopupPreview();
|
new SettingsPopupPreview();
|
||||||
})();
|
})();
|
||||||
|
@ -22,6 +22,7 @@
|
|||||||
* PopupProxy
|
* PopupProxy
|
||||||
* PopupProxyHost
|
* PopupProxyHost
|
||||||
* apiBroadcastTab
|
* apiBroadcastTab
|
||||||
|
* apiForwardLogsToBackend
|
||||||
* apiOptionsGet
|
* apiOptionsGet
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@ -62,6 +63,7 @@ async function createPopupProxy(depth, id, parentFrameId) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
(async () => {
|
(async () => {
|
||||||
|
apiForwardLogsToBackend();
|
||||||
await yomichan.prepare();
|
await yomichan.prepare();
|
||||||
|
|
||||||
const data = window.frontendInitializationData || {};
|
const data = window.frontendInitializationData || {};
|
||||||
|
@ -17,6 +17,7 @@
|
|||||||
|
|
||||||
/* global
|
/* global
|
||||||
* DisplayFloat
|
* DisplayFloat
|
||||||
|
* apiForwardLogsToBackend
|
||||||
* apiOptionsGet
|
* apiOptionsGet
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@ -68,5 +69,6 @@ async function popupNestedInitialize(id, depth, parentFrameId, url) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
(async () => {
|
(async () => {
|
||||||
|
apiForwardLogsToBackend();
|
||||||
new DisplayFloat();
|
new DisplayFloat();
|
||||||
})();
|
})();
|
||||||
|
@ -84,7 +84,7 @@ class DisplayFloat extends Display {
|
|||||||
if (this._orphaned) {
|
if (this._orphaned) {
|
||||||
this.setContent('orphaned');
|
this.setContent('orphaned');
|
||||||
} else {
|
} else {
|
||||||
logError(error, true);
|
yomichan.logError(error);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -81,12 +81,12 @@ class FrontendApiSender {
|
|||||||
onAck(id) {
|
onAck(id) {
|
||||||
const info = this.callbacks.get(id);
|
const info = this.callbacks.get(id);
|
||||||
if (typeof info === 'undefined') {
|
if (typeof info === 'undefined') {
|
||||||
console.warn(`ID ${id} not found for ack`);
|
yomichan.logWarning(new Error(`ID ${id} not found for ack`));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (info.ack) {
|
if (info.ack) {
|
||||||
console.warn(`Request ${id} already ack'd`);
|
yomichan.logWarning(new Error(`Request ${id} already ack'd`));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -98,12 +98,12 @@ class FrontendApiSender {
|
|||||||
onResult(id, data) {
|
onResult(id, data) {
|
||||||
const info = this.callbacks.get(id);
|
const info = this.callbacks.get(id);
|
||||||
if (typeof info === 'undefined') {
|
if (typeof info === 'undefined') {
|
||||||
console.warn(`ID ${id} not found`);
|
yomichan.logWarning(new Error(`ID ${id} not found`));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!info.ack) {
|
if (!info.ack) {
|
||||||
console.warn(`Request ${id} not ack'd`);
|
yomichan.logWarning(new Error(`Request ${id} not ack'd`));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -148,7 +148,7 @@ class PopupProxy {
|
|||||||
}
|
}
|
||||||
this._frameOffsetUpdatedAt = now;
|
this._frameOffsetUpdatedAt = now;
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
logError(e);
|
yomichan.logError(e);
|
||||||
} finally {
|
} finally {
|
||||||
this._frameOffsetPromise = null;
|
this._frameOffsetPromise = null;
|
||||||
}
|
}
|
||||||
|
@ -144,6 +144,14 @@ function apiGetMedia(targets) {
|
|||||||
return _apiInvoke('getMedia', {targets});
|
return _apiInvoke('getMedia', {targets});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function apiLog(error, level, context) {
|
||||||
|
return _apiInvoke('log', {error, level, context});
|
||||||
|
}
|
||||||
|
|
||||||
|
function apiLogIndicatorClear() {
|
||||||
|
return _apiInvoke('logIndicatorClear');
|
||||||
|
}
|
||||||
|
|
||||||
function _apiInvoke(action, params={}) {
|
function _apiInvoke(action, params={}) {
|
||||||
const data = {action, params};
|
const data = {action, params};
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
@ -171,3 +179,17 @@ function _apiInvoke(action, params={}) {
|
|||||||
function _apiCheckLastError() {
|
function _apiCheckLastError() {
|
||||||
// NOP
|
// NOP
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let _apiForwardLogsToBackendEnabled = false;
|
||||||
|
function apiForwardLogsToBackend() {
|
||||||
|
if (_apiForwardLogsToBackendEnabled) { return; }
|
||||||
|
_apiForwardLogsToBackendEnabled = true;
|
||||||
|
|
||||||
|
yomichan.on('log', async ({error, level, context}) => {
|
||||||
|
try {
|
||||||
|
await apiLog(errorToJson(error), level, context);
|
||||||
|
} catch (e) {
|
||||||
|
// NOP
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
@ -52,15 +52,28 @@ if (EXTENSION_IS_BROWSER_EDGE) {
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
function errorToJson(error) {
|
function errorToJson(error) {
|
||||||
|
try {
|
||||||
|
if (isObject(error)) {
|
||||||
|
return {
|
||||||
|
name: error.name,
|
||||||
|
message: error.message,
|
||||||
|
stack: error.stack,
|
||||||
|
data: error.data
|
||||||
|
};
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
// NOP
|
||||||
|
}
|
||||||
return {
|
return {
|
||||||
name: error.name,
|
value: error,
|
||||||
message: error.message,
|
hasValue: true
|
||||||
stack: error.stack,
|
|
||||||
data: error.data
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
function jsonToError(jsonError) {
|
function jsonToError(jsonError) {
|
||||||
|
if (jsonError.hasValue) {
|
||||||
|
return jsonError.value;
|
||||||
|
}
|
||||||
const error = new Error(jsonError.message);
|
const error = new Error(jsonError.message);
|
||||||
error.name = jsonError.name;
|
error.name = jsonError.name;
|
||||||
error.stack = jsonError.stack;
|
error.stack = jsonError.stack;
|
||||||
@ -68,28 +81,6 @@ function jsonToError(jsonError) {
|
|||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
function logError(error, alert) {
|
|
||||||
const manifest = chrome.runtime.getManifest();
|
|
||||||
let errorMessage = `${manifest.name} v${manifest.version} has encountered an error.\n`;
|
|
||||||
errorMessage += `Originating URL: ${window.location.href}\n`;
|
|
||||||
|
|
||||||
const errorString = `${error.toString ? error.toString() : error}`;
|
|
||||||
const stack = `${error.stack}`.trimRight();
|
|
||||||
if (!stack.startsWith(errorString)) { errorMessage += `${errorString}\n`; }
|
|
||||||
errorMessage += stack;
|
|
||||||
|
|
||||||
const data = error.data;
|
|
||||||
if (typeof data !== 'undefined') { errorMessage += `\nData: ${JSON.stringify(data, null, 4)}`; }
|
|
||||||
|
|
||||||
errorMessage += '\n\nIssues can be reported at https://github.com/FooSoft/yomichan/issues';
|
|
||||||
|
|
||||||
console.error(errorMessage);
|
|
||||||
|
|
||||||
if (alert) {
|
|
||||||
window.alert(`${errorString}\n\nCheck the developer console for more details.`);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Common helpers
|
* Common helpers
|
||||||
@ -361,8 +352,77 @@ const yomichan = (() => {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
logWarning(error) {
|
||||||
|
this.log(error, 'warn');
|
||||||
|
}
|
||||||
|
|
||||||
|
logError(error) {
|
||||||
|
this.log(error, 'error');
|
||||||
|
}
|
||||||
|
|
||||||
|
log(error, level, context=null) {
|
||||||
|
if (!isObject(context)) {
|
||||||
|
context = this._getLogContext();
|
||||||
|
}
|
||||||
|
|
||||||
|
let errorString;
|
||||||
|
try {
|
||||||
|
errorString = error.toString();
|
||||||
|
if (/^\[object \w+\]$/.test(errorString)) {
|
||||||
|
errorString = JSON.stringify(error);
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
errorString = `${error}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
let errorStack;
|
||||||
|
try {
|
||||||
|
errorStack = (typeof error.stack === 'string' ? error.stack.trimRight() : '');
|
||||||
|
} catch (e) {
|
||||||
|
errorStack = '';
|
||||||
|
}
|
||||||
|
|
||||||
|
let errorData;
|
||||||
|
try {
|
||||||
|
errorData = error.data;
|
||||||
|
} catch (e) {
|
||||||
|
// NOP
|
||||||
|
}
|
||||||
|
|
||||||
|
if (errorStack.startsWith(errorString)) {
|
||||||
|
errorString = errorStack;
|
||||||
|
} else if (errorStack.length > 0) {
|
||||||
|
errorString += `\n${errorStack}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
const manifest = chrome.runtime.getManifest();
|
||||||
|
let message = `${manifest.name} v${manifest.version} has encountered a problem.`;
|
||||||
|
message += `\nOriginating URL: ${context.url}\n`;
|
||||||
|
message += errorString;
|
||||||
|
if (typeof errorData !== 'undefined') {
|
||||||
|
message += `\nData: ${JSON.stringify(errorData, null, 4)}`;
|
||||||
|
}
|
||||||
|
message += '\n\nIssues can be reported at https://github.com/FooSoft/yomichan/issues';
|
||||||
|
|
||||||
|
switch (level) {
|
||||||
|
case 'info': console.info(message); break;
|
||||||
|
case 'debug': console.debug(message); break;
|
||||||
|
case 'warn': console.warn(message); break;
|
||||||
|
case 'error': console.error(message); break;
|
||||||
|
default: console.log(message); break;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.trigger('log', {error, level, context});
|
||||||
|
}
|
||||||
|
|
||||||
// Private
|
// Private
|
||||||
|
|
||||||
|
_getLogContext() {
|
||||||
|
return {
|
||||||
|
url: window.location.href
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
_onMessage({action, params}, sender, callback) {
|
_onMessage({action, params}, sender, callback) {
|
||||||
const handler = this._messageHandlers.get(action);
|
const handler = this._messageHandlers.get(action);
|
||||||
if (typeof handler !== 'function') { return false; }
|
if (typeof handler !== 'function') { return false; }
|
||||||
|
@ -201,7 +201,7 @@ class TextScanner {
|
|||||||
}
|
}
|
||||||
|
|
||||||
onError(error) {
|
onError(error) {
|
||||||
logError(error, false);
|
yomichan.logError(error);
|
||||||
}
|
}
|
||||||
|
|
||||||
async scanTimerWait() {
|
async scanTimerWait() {
|
||||||
|
@ -145,7 +145,10 @@ const vm = new VM({
|
|||||||
XMLHttpRequest,
|
XMLHttpRequest,
|
||||||
indexedDB: global.indexedDB,
|
indexedDB: global.indexedDB,
|
||||||
IDBKeyRange: global.IDBKeyRange,
|
IDBKeyRange: global.IDBKeyRange,
|
||||||
JSZip: yomichanTest.JSZip
|
JSZip: yomichanTest.JSZip,
|
||||||
|
addEventListener() {
|
||||||
|
// NOP
|
||||||
|
}
|
||||||
});
|
});
|
||||||
vm.context.window = vm.context;
|
vm.context.window = vm.context;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user