diff --git a/background-script.js b/background-script.js index 981eb17..695ca5b 100644 --- a/background-script.js +++ b/background-script.js @@ -109,7 +109,12 @@ async function refresh_json() for(let spelling of entries[i]["s"]) add_json_spelling(dict, spelling, i); } - } catch(e){} + } + catch(e) + { + console.log("error while loading/reloading json dictionary:"); + console.log(e); + } new_json_dicts.push(dict); } json_dicts = new_json_dicts; @@ -459,10 +464,10 @@ function search(text) k_ele.push({keb: spelling}); } let re_ret = undefined; - if(k_ele != []) - re_ret = [{k_ele: k_ele, r_ele: r_ele, seq: seq, sense: sense, from: text, found: k_ele[0]}]; - else + if(k_ele == undefined || k_ele.length == 0) re_ret = [{r_ele: r_ele, seq: seq, sense: sense, from: text, found: r_ele[0]}]; + else + re_ret = [{k_ele: k_ele, r_ele: r_ele, seq: seq, sense: sense, from: text, found: k_ele[0]}]; return re_ret; } } @@ -827,7 +832,12 @@ function deconjugate(mytext) { if(settings.deconjugator_rules_json != "") myrules = JSON.parse(settings.deconjugator_rules_json); - } catch(err) { console.log(err); } + } + catch(err) + { + console.log("error while parsing deconjugation rules:"); + console.log(err); + } while(novel.size > 0) { @@ -1731,23 +1741,41 @@ function lookup_indirect(text, time, divexisted, other_settings) { let results = []; let first = true; + console.log("collecting result for text `" + text + "`"); while(text.length > 0) { + console.log("current text: `" + text + "`"); let forms = deconjugate(text); let result = build_lookup_comb(forms); if(!first && other_settings.strict_alternatives && is_kana(text)) + { + console.log("filter-testing kana result"); result = filter_kana_ish_results(result); + } if(result !== undefined && result.length > 0) { - result = sort_results(text, result); + console.log("pushing result"); + console.log(result); + try + { + result = sort_results(text, result); + } + catch(e) + { + console.log("hit error sorting lookup results:"); + console.log(e); + console.log(result); + } results.push({text:text, result:result}); } text = text.substring(0, text.length-1); if(results.length > 0) first = false; } + console.log("results:"); + console.log(results); if(results.length > 0) return skip_rereferenced_entries(results, other_settings); } @@ -1794,7 +1822,7 @@ async function update_icon(enabled) "32": "img/enabled32.png", "512": "img/enabled512.png" }},); - } catch (err) {} + } catch (err) {} // don't care } else { @@ -1806,7 +1834,7 @@ async function update_icon(enabled) "32": "img/action32.png", "512": "img/action512.png" }},); - } catch (err) {} + } catch (err) {} // don't care } } @@ -1843,7 +1871,7 @@ function open_options(info, tab) browser.tabs.create({ url:browser.extension.getURL("options.html") }); - } catch(err) {} + } catch(err) {} // don't care } function open_reader(info, tab) @@ -1856,7 +1884,7 @@ function open_reader(info, tab) width:settings.reader_width, height:settings.reader_height }); - } catch(err) {} + } catch(err) {} // don't care } function open_mining(info, tab) { @@ -1866,7 +1894,7 @@ function open_mining(info, tab) url:browser.extension.getURL("mining.html"), type:"popup" }); - } catch(err) {} + } catch(err) {} // don't care } function open_livemining(info, tab) { @@ -1876,7 +1904,7 @@ function open_livemining(info, tab) url:browser.extension.getURL("livemining.html"), type:"popup" }); - } catch(err) {} + } catch(err) {} // don't care } function open_jsonconfig(info, tab) { @@ -1886,7 +1914,7 @@ function open_jsonconfig(info, tab) url:browser.extension.getURL("json_config.html"), type:"popup" }); - } catch(err) {} + } catch(err) {} // don't care } if(browser.contextMenus) @@ -1967,14 +1995,21 @@ function send_error(tab, error) try { browser.tabs.sendMessage(tab, {type:"error",error:error}); - } catch (err) {console.log("failed to send error to origin tab")} + } + catch (err) + { + console.log("failed to send error to origin tab"); + console.log(err); + } } browser.runtime.onMessage.addListener((req, sender) => { if (req.type == "search") { + console.log("opening lookup"); let asdf = lookup_indirect(req.text, req.time, req.divexisted, req.settings); + console.log("completing lookup"); return Promise.resolve({"response" : asdf}); } if (req.type == "search_kanji") @@ -2031,7 +2066,10 @@ browser.runtime.onMessage.addListener((req, sender) => newxhr.send('{"action": "sync","version": 6}'); } } - } catch (e) { + } + catch (e) + { + console.log("error while interacting with ankiconnect:"); console.log(e); } }); diff --git a/background.html b/background.html index ace5a08..3c93071 100644 --- a/background.html +++ b/background.html @@ -4,7 +4,6 @@ - diff --git a/include/browser-polyfill.min.js b/include/browser-polyfill.min.js deleted file mode 100644 index b3dd82d..0000000 --- a/include/browser-polyfill.min.js +++ /dev/null @@ -1,1186 +0,0 @@ -(function (global, factory) { - if (typeof define === "function" && define.amd) { - define("webextension-polyfill", ["module"], factory); - } else if (typeof exports !== "undefined") { - factory(module); - } else { - var mod = { - exports: {} - }; - factory(mod); - global.browser = mod.exports; - } -})(this, function (module) { - /* webextension-polyfill - v0.3.1 - Tue Aug 21 2018 10:09:34 */ - /* -*- Mode: indent-tabs-mode: nil; js-indent-level: 2 -*- */ - /* vim: set sts=2 sw=2 et tw=80: */ - /* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - "use strict"; - - if (typeof browser === "undefined" || Object.getPrototypeOf(browser) !== Object.prototype) { - const CHROME_SEND_MESSAGE_CALLBACK_NO_RESPONSE_MESSAGE = "The message port closed before a response was received."; - const SEND_RESPONSE_DEPRECATION_WARNING = "Returning a Promise is the preferred way to send a reply from an onMessage/onMessageExternal listener, as the sendResponse will be removed from the specs (See https://developer.mozilla.org/docs/Mozilla/Add-ons/WebExtensions/API/runtime/onMessage)"; - - // Wrapping the bulk of this polyfill in a one-time-use function is a minor - // optimization for Firefox. Since Spidermonkey does not fully parse the - // contents of a function until the first time it's called, and since it will - // never actually need to be called, this allows the polyfill to be included - // in Firefox nearly for free. - const wrapAPIs = () => { - // NOTE: apiMetadata is associated to the content of the api-metadata.json file - // at build time by replacing the following "include" with the content of the - // JSON file. - const apiMetadata = { - "alarms": { - "clear": { - "minArgs": 0, - "maxArgs": 1 - }, - "clearAll": { - "minArgs": 0, - "maxArgs": 0 - }, - "get": { - "minArgs": 0, - "maxArgs": 1 - }, - "getAll": { - "minArgs": 0, - "maxArgs": 0 - } - }, - "bookmarks": { - "create": { - "minArgs": 1, - "maxArgs": 1 - }, - "get": { - "minArgs": 1, - "maxArgs": 1 - }, - "getChildren": { - "minArgs": 1, - "maxArgs": 1 - }, - "getRecent": { - "minArgs": 1, - "maxArgs": 1 - }, - "getSubTree": { - "minArgs": 1, - "maxArgs": 1 - }, - "getTree": { - "minArgs": 0, - "maxArgs": 0 - }, - "move": { - "minArgs": 2, - "maxArgs": 2 - }, - "remove": { - "minArgs": 1, - "maxArgs": 1 - }, - "removeTree": { - "minArgs": 1, - "maxArgs": 1 - }, - "search": { - "minArgs": 1, - "maxArgs": 1 - }, - "update": { - "minArgs": 2, - "maxArgs": 2 - } - }, - "browserAction": { - "disable": { - "minArgs": 0, - "maxArgs": 1, - "fallbackToNoCallback": true - }, - "enable": { - "minArgs": 0, - "maxArgs": 1, - "fallbackToNoCallback": true - }, - "getBadgeBackgroundColor": { - "minArgs": 1, - "maxArgs": 1 - }, - "getBadgeText": { - "minArgs": 1, - "maxArgs": 1 - }, - "getPopup": { - "minArgs": 1, - "maxArgs": 1 - }, - "getTitle": { - "minArgs": 1, - "maxArgs": 1 - }, - "openPopup": { - "minArgs": 0, - "maxArgs": 0 - }, - "setBadgeBackgroundColor": { - "minArgs": 1, - "maxArgs": 1, - "fallbackToNoCallback": true - }, - "setBadgeText": { - "minArgs": 1, - "maxArgs": 1, - "fallbackToNoCallback": true - }, - "setIcon": { - "minArgs": 1, - "maxArgs": 1 - }, - "setPopup": { - "minArgs": 1, - "maxArgs": 1, - "fallbackToNoCallback": true - }, - "setTitle": { - "minArgs": 1, - "maxArgs": 1, - "fallbackToNoCallback": true - } - }, - "browsingData": { - "remove": { - "minArgs": 2, - "maxArgs": 2 - }, - "removeCache": { - "minArgs": 1, - "maxArgs": 1 - }, - "removeCookies": { - "minArgs": 1, - "maxArgs": 1 - }, - "removeDownloads": { - "minArgs": 1, - "maxArgs": 1 - }, - "removeFormData": { - "minArgs": 1, - "maxArgs": 1 - }, - "removeHistory": { - "minArgs": 1, - "maxArgs": 1 - }, - "removeLocalStorage": { - "minArgs": 1, - "maxArgs": 1 - }, - "removePasswords": { - "minArgs": 1, - "maxArgs": 1 - }, - "removePluginData": { - "minArgs": 1, - "maxArgs": 1 - }, - "settings": { - "minArgs": 0, - "maxArgs": 0 - } - }, - "commands": { - "getAll": { - "minArgs": 0, - "maxArgs": 0 - } - }, - "contextMenus": { - "remove": { - "minArgs": 1, - "maxArgs": 1 - }, - "removeAll": { - "minArgs": 0, - "maxArgs": 0 - }, - "update": { - "minArgs": 2, - "maxArgs": 2 - } - }, - "cookies": { - "get": { - "minArgs": 1, - "maxArgs": 1 - }, - "getAll": { - "minArgs": 1, - "maxArgs": 1 - }, - "getAllCookieStores": { - "minArgs": 0, - "maxArgs": 0 - }, - "remove": { - "minArgs": 1, - "maxArgs": 1 - }, - "set": { - "minArgs": 1, - "maxArgs": 1 - } - }, - "devtools": { - "inspectedWindow": { - "eval": { - "minArgs": 1, - "maxArgs": 2 - } - }, - "panels": { - "create": { - "minArgs": 3, - "maxArgs": 3, - "singleCallbackArg": true - } - } - }, - "downloads": { - "cancel": { - "minArgs": 1, - "maxArgs": 1 - }, - "download": { - "minArgs": 1, - "maxArgs": 1 - }, - "erase": { - "minArgs": 1, - "maxArgs": 1 - }, - "getFileIcon": { - "minArgs": 1, - "maxArgs": 2 - }, - "open": { - "minArgs": 1, - "maxArgs": 1, - "fallbackToNoCallback": true - }, - "pause": { - "minArgs": 1, - "maxArgs": 1 - }, - "removeFile": { - "minArgs": 1, - "maxArgs": 1 - }, - "resume": { - "minArgs": 1, - "maxArgs": 1 - }, - "search": { - "minArgs": 1, - "maxArgs": 1 - }, - "show": { - "minArgs": 1, - "maxArgs": 1, - "fallbackToNoCallback": true - } - }, - "extension": { - "isAllowedFileSchemeAccess": { - "minArgs": 0, - "maxArgs": 0 - }, - "isAllowedIncognitoAccess": { - "minArgs": 0, - "maxArgs": 0 - } - }, - "history": { - "addUrl": { - "minArgs": 1, - "maxArgs": 1 - }, - "deleteAll": { - "minArgs": 0, - "maxArgs": 0 - }, - "deleteRange": { - "minArgs": 1, - "maxArgs": 1 - }, - "deleteUrl": { - "minArgs": 1, - "maxArgs": 1 - }, - "getVisits": { - "minArgs": 1, - "maxArgs": 1 - }, - "search": { - "minArgs": 1, - "maxArgs": 1 - } - }, - "i18n": { - "detectLanguage": { - "minArgs": 1, - "maxArgs": 1 - }, - "getAcceptLanguages": { - "minArgs": 0, - "maxArgs": 0 - } - }, - "identity": { - "launchWebAuthFlow": { - "minArgs": 1, - "maxArgs": 1 - } - }, - "idle": { - "queryState": { - "minArgs": 1, - "maxArgs": 1 - } - }, - "management": { - "get": { - "minArgs": 1, - "maxArgs": 1 - }, - "getAll": { - "minArgs": 0, - "maxArgs": 0 - }, - "getSelf": { - "minArgs": 0, - "maxArgs": 0 - }, - "setEnabled": { - "minArgs": 2, - "maxArgs": 2 - }, - "uninstallSelf": { - "minArgs": 0, - "maxArgs": 1 - } - }, - "notifications": { - "clear": { - "minArgs": 1, - "maxArgs": 1 - }, - "create": { - "minArgs": 1, - "maxArgs": 2 - }, - "getAll": { - "minArgs": 0, - "maxArgs": 0 - }, - "getPermissionLevel": { - "minArgs": 0, - "maxArgs": 0 - }, - "update": { - "minArgs": 2, - "maxArgs": 2 - } - }, - "pageAction": { - "getPopup": { - "minArgs": 1, - "maxArgs": 1 - }, - "getTitle": { - "minArgs": 1, - "maxArgs": 1 - }, - "hide": { - "minArgs": 1, - "maxArgs": 1, - "fallbackToNoCallback": true - }, - "setIcon": { - "minArgs": 1, - "maxArgs": 1 - }, - "setPopup": { - "minArgs": 1, - "maxArgs": 1, - "fallbackToNoCallback": true - }, - "setTitle": { - "minArgs": 1, - "maxArgs": 1, - "fallbackToNoCallback": true - }, - "show": { - "minArgs": 1, - "maxArgs": 1, - "fallbackToNoCallback": true - } - }, - "permissions": { - "contains": { - "minArgs": 1, - "maxArgs": 1 - }, - "getAll": { - "minArgs": 0, - "maxArgs": 0 - }, - "remove": { - "minArgs": 1, - "maxArgs": 1 - }, - "request": { - "minArgs": 1, - "maxArgs": 1 - } - }, - "runtime": { - "getBackgroundPage": { - "minArgs": 0, - "maxArgs": 0 - }, - "getBrowserInfo": { - "minArgs": 0, - "maxArgs": 0 - }, - "getPlatformInfo": { - "minArgs": 0, - "maxArgs": 0 - }, - "openOptionsPage": { - "minArgs": 0, - "maxArgs": 0 - }, - "requestUpdateCheck": { - "minArgs": 0, - "maxArgs": 0 - }, - "sendMessage": { - "minArgs": 1, - "maxArgs": 3 - }, - "sendNativeMessage": { - "minArgs": 2, - "maxArgs": 2 - }, - "setUninstallURL": { - "minArgs": 1, - "maxArgs": 1 - } - }, - "sessions": { - "getDevices": { - "minArgs": 0, - "maxArgs": 1 - }, - "getRecentlyClosed": { - "minArgs": 0, - "maxArgs": 1 - }, - "restore": { - "minArgs": 0, - "maxArgs": 1 - } - }, - "storage": { - "local": { - "clear": { - "minArgs": 0, - "maxArgs": 0 - }, - "get": { - "minArgs": 0, - "maxArgs": 1 - }, - "getBytesInUse": { - "minArgs": 0, - "maxArgs": 1 - }, - "remove": { - "minArgs": 1, - "maxArgs": 1 - }, - "set": { - "minArgs": 1, - "maxArgs": 1 - } - }, - "managed": { - "get": { - "minArgs": 0, - "maxArgs": 1 - }, - "getBytesInUse": { - "minArgs": 0, - "maxArgs": 1 - } - }, - "sync": { - "clear": { - "minArgs": 0, - "maxArgs": 0 - }, - "get": { - "minArgs": 0, - "maxArgs": 1 - }, - "getBytesInUse": { - "minArgs": 0, - "maxArgs": 1 - }, - "remove": { - "minArgs": 1, - "maxArgs": 1 - }, - "set": { - "minArgs": 1, - "maxArgs": 1 - } - } - }, - "tabs": { - "captureVisibleTab": { - "minArgs": 0, - "maxArgs": 2 - }, - "create": { - "minArgs": 1, - "maxArgs": 1 - }, - "detectLanguage": { - "minArgs": 0, - "maxArgs": 1 - }, - "discard": { - "minArgs": 0, - "maxArgs": 1 - }, - "duplicate": { - "minArgs": 1, - "maxArgs": 1 - }, - "executeScript": { - "minArgs": 1, - "maxArgs": 2 - }, - "get": { - "minArgs": 1, - "maxArgs": 1 - }, - "getCurrent": { - "minArgs": 0, - "maxArgs": 0 - }, - "getZoom": { - "minArgs": 0, - "maxArgs": 1 - }, - "getZoomSettings": { - "minArgs": 0, - "maxArgs": 1 - }, - "highlight": { - "minArgs": 1, - "maxArgs": 1 - }, - "insertCSS": { - "minArgs": 1, - "maxArgs": 2 - }, - "move": { - "minArgs": 2, - "maxArgs": 2 - }, - "query": { - "minArgs": 1, - "maxArgs": 1 - }, - "reload": { - "minArgs": 0, - "maxArgs": 2 - }, - "remove": { - "minArgs": 1, - "maxArgs": 1 - }, - "removeCSS": { - "minArgs": 1, - "maxArgs": 2 - }, - "sendMessage": { - "minArgs": 2, - "maxArgs": 3 - }, - "setZoom": { - "minArgs": 1, - "maxArgs": 2 - }, - "setZoomSettings": { - "minArgs": 1, - "maxArgs": 2 - }, - "update": { - "minArgs": 1, - "maxArgs": 2 - } - }, - "topSites": { - "get": { - "minArgs": 0, - "maxArgs": 0 - } - }, - "webNavigation": { - "getAllFrames": { - "minArgs": 1, - "maxArgs": 1 - }, - "getFrame": { - "minArgs": 1, - "maxArgs": 1 - } - }, - "webRequest": { - "handlerBehaviorChanged": { - "minArgs": 0, - "maxArgs": 0 - } - }, - "windows": { - "create": { - "minArgs": 0, - "maxArgs": 1 - }, - "get": { - "minArgs": 1, - "maxArgs": 2 - }, - "getAll": { - "minArgs": 0, - "maxArgs": 1 - }, - "getCurrent": { - "minArgs": 0, - "maxArgs": 1 - }, - "getLastFocused": { - "minArgs": 0, - "maxArgs": 1 - }, - "remove": { - "minArgs": 1, - "maxArgs": 1 - }, - "update": { - "minArgs": 2, - "maxArgs": 2 - } - } - }; - - if (Object.keys(apiMetadata).length === 0) { - throw new Error("api-metadata.json has not been included in browser-polyfill"); - } - - /** - * A WeakMap subclass which creates and stores a value for any key which does - * not exist when accessed, but behaves exactly as an ordinary WeakMap - * otherwise. - * - * @param {function} createItem - * A function which will be called in order to create the value for any - * key which does not exist, the first time it is accessed. The - * function receives, as its only argument, the key being created. - */ - class DefaultWeakMap extends WeakMap { - constructor(createItem, items = undefined) { - super(items); - this.createItem = createItem; - } - - get(key) { - if (!this.has(key)) { - this.set(key, this.createItem(key)); - } - - return super.get(key); - } - } - - /** - * Returns true if the given object is an object with a `then` method, and can - * therefore be assumed to behave as a Promise. - * - * @param {*} value The value to test. - * @returns {boolean} True if the value is thenable. - */ - const isThenable = value => { - return value && typeof value === "object" && typeof value.then === "function"; - }; - - /** - * Creates and returns a function which, when called, will resolve or reject - * the given promise based on how it is called: - * - * - If, when called, `chrome.runtime.lastError` contains a non-null object, - * the promise is rejected with that value. - * - If the function is called with exactly one argument, the promise is - * resolved to that value. - * - Otherwise, the promise is resolved to an array containing all of the - * function's arguments. - * - * @param {object} promise - * An object containing the resolution and rejection functions of a - * promise. - * @param {function} promise.resolve - * The promise's resolution function. - * @param {function} promise.rejection - * The promise's rejection function. - * @param {object} metadata - * Metadata about the wrapped method which has created the callback. - * @param {integer} metadata.maxResolvedArgs - * The maximum number of arguments which may be passed to the - * callback created by the wrapped async function. - * - * @returns {function} - * The generated callback function. - */ - const makeCallback = (promise, metadata) => { - return (...callbackArgs) => { - if (chrome.runtime.lastError) { - promise.reject(chrome.runtime.lastError); - } else if (metadata.singleCallbackArg || callbackArgs.length <= 1) { - promise.resolve(callbackArgs[0]); - } else { - promise.resolve(callbackArgs); - } - }; - }; - - const pluralizeArguments = numArgs => numArgs == 1 ? "argument" : "arguments"; - - /** - * Creates a wrapper function for a method with the given name and metadata. - * - * @param {string} name - * The name of the method which is being wrapped. - * @param {object} metadata - * Metadata about the method being wrapped. - * @param {integer} metadata.minArgs - * The minimum number of arguments which must be passed to the - * function. If called with fewer than this number of arguments, the - * wrapper will raise an exception. - * @param {integer} metadata.maxArgs - * The maximum number of arguments which may be passed to the - * function. If called with more than this number of arguments, the - * wrapper will raise an exception. - * @param {integer} metadata.maxResolvedArgs - * The maximum number of arguments which may be passed to the - * callback created by the wrapped async function. - * - * @returns {function(object, ...*)} - * The generated wrapper function. - */ - const wrapAsyncFunction = (name, metadata) => { - return function asyncFunctionWrapper(target, ...args) { - if (args.length < metadata.minArgs) { - throw new Error(`Expected at least ${metadata.minArgs} ${pluralizeArguments(metadata.minArgs)} for ${name}(), got ${args.length}`); - } - - if (args.length > metadata.maxArgs) { - throw new Error(`Expected at most ${metadata.maxArgs} ${pluralizeArguments(metadata.maxArgs)} for ${name}(), got ${args.length}`); - } - - return new Promise((resolve, reject) => { - if (metadata.fallbackToNoCallback) { - // This API method has currently no callback on Chrome, but it return a promise on Firefox, - // and so the polyfill will try to call it with a callback first, and it will fallback - // to not passing the callback if the first call fails. - try { - target[name](...args, makeCallback({ resolve, reject }, metadata)); - } catch (cbError) { - console.warn(`${name} API method doesn't seem to support the callback parameter, ` + "falling back to call it without a callback: ", cbError); - - target[name](...args); - - // Update the API method metadata, so that the next API calls will not try to - // use the unsupported callback anymore. - metadata.fallbackToNoCallback = false; - metadata.noCallback = true; - - resolve(); - } - } else if (metadata.noCallback) { - target[name](...args); - resolve(); - } else { - target[name](...args, makeCallback({ resolve, reject }, metadata)); - } - }); - }; - }; - - /** - * Wraps an existing method of the target object, so that calls to it are - * intercepted by the given wrapper function. The wrapper function receives, - * as its first argument, the original `target` object, followed by each of - * the arguments passed to the original method. - * - * @param {object} target - * The original target object that the wrapped method belongs to. - * @param {function} method - * The method being wrapped. This is used as the target of the Proxy - * object which is created to wrap the method. - * @param {function} wrapper - * The wrapper function which is called in place of a direct invocation - * of the wrapped method. - * - * @returns {Proxy} - * A Proxy object for the given method, which invokes the given wrapper - * method in its place. - */ - const wrapMethod = (target, method, wrapper) => { - return new Proxy(method, { - apply(targetMethod, thisObj, args) { - return wrapper.call(thisObj, target, ...args); - } - }); - }; - - let hasOwnProperty = Function.call.bind(Object.prototype.hasOwnProperty); - - /** - * Wraps an object in a Proxy which intercepts and wraps certain methods - * based on the given `wrappers` and `metadata` objects. - * - * @param {object} target - * The target object to wrap. - * - * @param {object} [wrappers = {}] - * An object tree containing wrapper functions for special cases. Any - * function present in this object tree is called in place of the - * method in the same location in the `target` object tree. These - * wrapper methods are invoked as described in {@see wrapMethod}. - * - * @param {object} [metadata = {}] - * An object tree containing metadata used to automatically generate - * Promise-based wrapper functions for asynchronous. Any function in - * the `target` object tree which has a corresponding metadata object - * in the same location in the `metadata` tree is replaced with an - * automatically-generated wrapper function, as described in - * {@see wrapAsyncFunction} - * - * @returns {Proxy} - */ - const wrapObject = (target, wrappers = {}, metadata = {}) => { - let cache = Object.create(null); - let handlers = { - has(proxyTarget, prop) { - return prop in target || prop in cache; - }, - - get(proxyTarget, prop, receiver) { - if (prop in cache) { - return cache[prop]; - } - - if (!(prop in target)) { - return undefined; - } - - let value = target[prop]; - - if (typeof value === "function") { - // This is a method on the underlying object. Check if we need to do - // any wrapping. - - if (typeof wrappers[prop] === "function") { - // We have a special-case wrapper for this method. - value = wrapMethod(target, target[prop], wrappers[prop]); - } else if (hasOwnProperty(metadata, prop)) { - // This is an async method that we have metadata for. Create a - // Promise wrapper for it. - let wrapper = wrapAsyncFunction(prop, metadata[prop]); - value = wrapMethod(target, target[prop], wrapper); - } else { - // This is a method that we don't know or care about. Return the - // original method, bound to the underlying object. - value = value.bind(target); - } - } else if (typeof value === "object" && value !== null && (hasOwnProperty(wrappers, prop) || hasOwnProperty(metadata, prop))) { - // This is an object that we need to do some wrapping for the children - // of. Create a sub-object wrapper for it with the appropriate child - // metadata. - value = wrapObject(value, wrappers[prop], metadata[prop]); - } else { - // We don't need to do any wrapping for this property, - // so just forward all access to the underlying object. - Object.defineProperty(cache, prop, { - configurable: true, - enumerable: true, - get() { - return target[prop]; - }, - set(value) { - target[prop] = value; - } - }); - - return value; - } - - cache[prop] = value; - return value; - }, - - set(proxyTarget, prop, value, receiver) { - if (prop in cache) { - cache[prop] = value; - } else { - target[prop] = value; - } - return true; - }, - - defineProperty(proxyTarget, prop, desc) { - return Reflect.defineProperty(cache, prop, desc); - }, - - deleteProperty(proxyTarget, prop) { - return Reflect.deleteProperty(cache, prop); - } - }; - - // Per contract of the Proxy API, the "get" proxy handler must return the - // original value of the target if that value is declared read-only and - // non-configurable. For this reason, we create an object with the - // prototype set to `target` instead of using `target` directly. - // Otherwise we cannot return a custom object for APIs that - // are declared read-only and non-configurable, such as `chrome.devtools`. - // - // The proxy handlers themselves will still use the original `target` - // instead of the `proxyTarget`, so that the methods and properties are - // dereferenced via the original targets. - let proxyTarget = Object.create(target); - return new Proxy(proxyTarget, handlers); - }; - - /** - * Creates a set of wrapper functions for an event object, which handles - * wrapping of listener functions that those messages are passed. - * - * A single wrapper is created for each listener function, and stored in a - * map. Subsequent calls to `addListener`, `hasListener`, or `removeListener` - * retrieve the original wrapper, so that attempts to remove a - * previously-added listener work as expected. - * - * @param {DefaultWeakMap} wrapperMap - * A DefaultWeakMap object which will create the appropriate wrapper - * for a given listener function when one does not exist, and retrieve - * an existing one when it does. - * - * @returns {object} - */ - const wrapEvent = wrapperMap => ({ - addListener(target, listener, ...args) { - target.addListener(wrapperMap.get(listener), ...args); - }, - - hasListener(target, listener) { - return target.hasListener(wrapperMap.get(listener)); - }, - - removeListener(target, listener) { - target.removeListener(wrapperMap.get(listener)); - } - }); - - // Keep track if the deprecation warning has been logged at least once. - let loggedSendResponseDeprecationWarning = false; - - const onMessageWrappers = new DefaultWeakMap(listener => { - if (typeof listener !== "function") { - return listener; - } - - /** - * Wraps a message listener function so that it may send responses based on - * its return value, rather than by returning a sentinel value and calling a - * callback. If the listener function returns a Promise, the response is - * sent when the promise either resolves or rejects. - * - * @param {*} message - * The message sent by the other end of the channel. - * @param {object} sender - * Details about the sender of the message. - * @param {function(*)} sendResponse - * A callback which, when called with an arbitrary argument, sends - * that value as a response. - * @returns {boolean} - * True if the wrapped listener returned a Promise, which will later - * yield a response. False otherwise. - */ - return function onMessage(message, sender, sendResponse) { - let didCallSendResponse = false; - - let wrappedSendResponse; - let sendResponsePromise = new Promise(resolve => { - wrappedSendResponse = function (response) { - if (!loggedSendResponseDeprecationWarning) { - console.warn(SEND_RESPONSE_DEPRECATION_WARNING, new Error().stack); - loggedSendResponseDeprecationWarning = true; - } - didCallSendResponse = true; - resolve(response); - }; - }); - - let result; - try { - result = listener(message, sender, wrappedSendResponse); - } catch (err) { - result = Promise.reject(err); - } - - const isResultThenable = result !== true && isThenable(result); - - // If the listener didn't returned true or a Promise, or called - // wrappedSendResponse synchronously, we can exit earlier - // because there will be no response sent from this listener. - if (result !== true && !isResultThenable && !didCallSendResponse) { - return false; - } - - // A small helper to send the message if the promise resolves - // and an error if the promise rejects (a wrapped sendMessage has - // to translate the message into a resolved promise or a rejected - // promise). - const sendPromisedResult = promise => { - promise.then(msg => { - // send the message value. - sendResponse(msg); - }, error => { - // Send a JSON representation of the error if the rejected value - // is an instance of error, or the object itself otherwise. - let message; - if (error && (error instanceof Error || typeof error.message === "string")) { - message = error.message; - } else { - message = "An unexpected error occurred"; - } - - sendResponse({ - __mozWebExtensionPolyfillReject__: true, - message - }); - }).catch(err => { - // Print an error on the console if unable to send the response. - console.error("Failed to send onMessage rejected reply", err); - }); - }; - - // If the listener returned a Promise, send the resolved value as a - // result, otherwise wait the promise related to the wrappedSendResponse - // callback to resolve and send it as a response. - if (isResultThenable) { - sendPromisedResult(result); - } else { - sendPromisedResult(sendResponsePromise); - } - - // Let Chrome know that the listener is replying. - return true; - }; - }); - - const wrappedSendMessageCallback = ({ reject, resolve }, reply) => { - if (chrome.runtime.lastError) { - // Detect when none of the listeners replied to the sendMessage call and resolve - // the promise to undefined as in Firefox. - // See https://github.com/mozilla/webextension-polyfill/issues/130 - if (chrome.runtime.lastError.message === CHROME_SEND_MESSAGE_CALLBACK_NO_RESPONSE_MESSAGE) { - resolve(); - } else { - reject(chrome.runtime.lastError); - } - } else if (reply && reply.__mozWebExtensionPolyfillReject__) { - // Convert back the JSON representation of the error into - // an Error instance. - reject(new Error(reply.message)); - } else { - resolve(reply); - } - }; - - const wrappedSendMessage = (name, metadata, apiNamespaceObj, ...args) => { - if (args.length < metadata.minArgs) { - throw new Error(`Expected at least ${metadata.minArgs} ${pluralizeArguments(metadata.minArgs)} for ${name}(), got ${args.length}`); - } - - if (args.length > metadata.maxArgs) { - throw new Error(`Expected at most ${metadata.maxArgs} ${pluralizeArguments(metadata.maxArgs)} for ${name}(), got ${args.length}`); - } - - return new Promise((resolve, reject) => { - const wrappedCb = wrappedSendMessageCallback.bind(null, { resolve, reject }); - args.push(wrappedCb); - apiNamespaceObj.sendMessage(...args); - }); - }; - - const staticWrappers = { - runtime: { - onMessage: wrapEvent(onMessageWrappers), - onMessageExternal: wrapEvent(onMessageWrappers), - sendMessage: wrappedSendMessage.bind(null, "sendMessage", { minArgs: 1, maxArgs: 3 }) - }, - tabs: { - sendMessage: wrappedSendMessage.bind(null, "sendMessage", { minArgs: 2, maxArgs: 3 }) - } - }; - const settingMetadata = { - clear: { minArgs: 1, maxArgs: 1 }, - get: { minArgs: 1, maxArgs: 1 }, - set: { minArgs: 1, maxArgs: 1 } - }; - apiMetadata.privacy = { - network: { - networkPredictionEnabled: settingMetadata, - webRTCIPHandlingPolicy: settingMetadata - }, - services: { - passwordSavingEnabled: settingMetadata - }, - websites: { - hyperlinkAuditingEnabled: settingMetadata, - referrersEnabled: settingMetadata - } - }; - - return wrapObject(chrome, staticWrappers, apiMetadata); - }; - - // The build process adds a UMD wrapper around this file, which makes the - // `module` variable available. - module.exports = wrapAPIs(); // eslint-disable-line no-undef - } else { - module.exports = browser; // eslint-disable-line no-undef - } -}); -//# sourceMappingURL=browser-polyfill.js.map diff --git a/json_config.html b/json_config.html index 96a4b3f..d86e100 100644 --- a/json_config.html +++ b/json_config.html @@ -45,7 +45,6 @@ div.closed display: none; } - diff --git a/livemining.html b/livemining.html index 138c233..709a0b8 100644 --- a/livemining.html +++ b/livemining.html @@ -5,7 +5,6 @@ Nazeka: Configuration for Live Mining - - diff --git a/options.html b/options.html index f62becb..1f135d0 100644 --- a/options.html +++ b/options.html @@ -5,7 +5,6 @@ Nazeka: options - - diff --git a/texthook.js b/texthook.js index 2709a5e..3ecfb3d 100644 --- a/texthook.js +++ b/texthook.js @@ -92,14 +92,14 @@ async function get_real_platform() my_platform = await browser.runtime.sendMessage({type:"platform"}); if(my_platform) my_platform = my_platform["response"]; - }catch(err){} + }catch(err){}// don't care while(my_platform == "") { try { my_platform = await browser.runtime.sendMessage({type:"platform"}); if(my_platform) my_platform = my_platform["response"]; - }catch(err){} + }catch(err){}// don't care } platform = my_platform; } @@ -170,7 +170,7 @@ function get_doc() } catch(err) { - console.log("hit error"); + console.log("hit error trying to find root; nazeka might behave incoherently"); console.log(err); break; } @@ -1616,7 +1616,7 @@ function selection_rejects_node(selection_range, textNode, offset) if(!selection_range.isPointInRange(textNode, offset) || !selection_range.isPointInRange(textNode, offset+1)) return true; } - catch(e){} + catch(e){} // selection range was strange return false; } @@ -1678,6 +1678,7 @@ function get_element_text_with_offsets(element, selection_range) } catch(err) { + console.log("encountered error while trying to grab element text"); console.log(err); } return ["", 0]; @@ -1727,7 +1728,7 @@ function grab_more_text(textNode, selection_range, direction = 1) if(ruby_interior || !inline_like) break; } - catch(err){} + catch(err){} // doesn't work with getComputedStyle or maybe tagName } if(iters > 100) { @@ -1962,7 +1963,7 @@ function update(event) let z_index = toreset[1]; element.style.zIndex = z_index; } - catch (err){} + catch (err){} // don't care just reset everything correctly } } @@ -2085,7 +2086,7 @@ function update(event) return; } } - catch(e){ } + catch(e){ } // window.getSelection() was null or null-like } // if there was text, use it