aboutsummaryrefslogtreecommitdiff
path: root/ext/mixed/js/core.js
diff options
context:
space:
mode:
authorAlex Yatskov <alex@foosoft.net>2020-05-22 17:46:16 -0700
committerAlex Yatskov <alex@foosoft.net>2020-05-22 17:46:16 -0700
commit1480288561cb8b9fb87ad711d970c548329fea98 (patch)
tree87c2247f6d144407afcc6de316bbacc264582248 /ext/mixed/js/core.js
parentf2186c51e4ef219d158735d30a32bbf3e49c4e1a (diff)
parentd0dcff765f740bf6f0f6523b09cb8b21eb85cd93 (diff)
Merge branch 'master' into testing
Diffstat (limited to 'ext/mixed/js/core.js')
-rw-r--r--ext/mixed/js/core.js132
1 files changed, 106 insertions, 26 deletions
diff --git a/ext/mixed/js/core.js b/ext/mixed/js/core.js
index 2d11c11a..589425f2 100644
--- a/ext/mixed/js/core.js
+++ b/ext/mixed/js/core.js
@@ -52,15 +52,28 @@ if (EXTENSION_IS_BROWSER_EDGE) {
*/
function errorToJson(error) {
+ try {
+ if (isObject(error)) {
+ return {
+ name: error.name,
+ message: error.message,
+ stack: error.stack,
+ data: error.data
+ };
+ }
+ } catch (e) {
+ // NOP
+ }
return {
- name: error.name,
- message: error.message,
- stack: error.stack,
- data: error.data
+ value: error,
+ hasValue: true
};
}
function jsonToError(jsonError) {
+ if (jsonError.hasValue) {
+ return jsonError.value;
+ }
const error = new Error(jsonError.message);
error.name = jsonError.name;
error.stack = jsonError.stack;
@@ -68,28 +81,6 @@ function jsonToError(jsonError) {
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
@@ -103,6 +94,11 @@ function hasOwn(object, property) {
return Object.prototype.hasOwnProperty.call(object, property);
}
+// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expressions
+function escapeRegExp(string) {
+ return string.replace(/[.*+\-?^${}()|[\]\\]/g, '\\$&');
+}
+
// toIterable is required on Edge for cross-window origin objects.
function toIterable(value) {
if (typeof Symbol !== 'undefined' && typeof value[Symbol.iterator] !== 'undefined') {
@@ -155,6 +151,12 @@ function getSetIntersection(set1, set2) {
return result;
}
+function getSetDifference(set1, set2) {
+ return new Set(
+ [...set1].filter((value) => !set2.has(value))
+ );
+}
+
/*
* Async utilities
@@ -316,6 +318,15 @@ const yomichan = (() => {
this.trigger('orphaned', {error});
}
+ isExtensionUrl(url) {
+ try {
+ const urlBase = chrome.runtime.getURL('/');
+ return url.substring(0, urlBase.length) === urlBase;
+ } catch (e) {
+ return false;
+ }
+ }
+
getTemporaryListenerResult(eventHandler, userCallback, timeout=null) {
if (!(
typeof eventHandler.addListener === 'function' &&
@@ -352,8 +363,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
+ _getLogContext() {
+ return {
+ url: window.location.href
+ };
+ }
+
_onMessage({action, params}, sender, callback) {
const handler = this._messageHandlers.get(action);
if (typeof handler !== 'function') { return false; }