Files
nazeka-chromium/background-script.js
T
2017-12-08 18:09:29 -05:00

144 lines
3.9 KiB
JavaScript

// Copyright 2017; Licensed under the Apache License, Version 2.0: https://www.apache.org/licenses/LICENSE-2.0
'use strict';
// We use JMdict converted to JSON. It's like 32MB so we don't want to load it for every tab.
// So we need to use a backgroudn script and send messages to it from the content script.
// Unfortunately webextensions don't have an easy way to load files even from in extension.
// We have to send an HTTP request and store the result in a string before parsing it into an object.
// Seriously.
let text = "";
function listener()
{
if (this.readyState === 4)
{
if (this.status === 200)
text = this.responseText;
else
console.error(xhr.statusText);
}
}
let req = new XMLHttpRequest();
req.addEventListener("load", listener);
// FIXME: apparently this has to be in an async function now.
req.open("GET", browser.extension.getURL("dict/JMdict.json"), false);
req.send();
let dict = JSON.parse(text);
text = "";
// Build map of spellings to dictionary entry.
let lookup_kan = {};
let lookup_kana = {};
for (let i = 0; i < dict.length; i++)
{
let entry = dict[i];
if (entry.k_ele != undefined) for (let j = 0; j < entry.k_ele.length; j++)
{
let s = entry.k_ele[j];
if (lookup_kan[s.keb] == undefined)
lookup_kan[s.keb] = [i];
else
lookup_kan[s.keb].push(i);
}
for (let j = 0; j < entry.r_ele.length; j++)
{
let s = entry.r_ele[j];
if (lookup_kana[s.reb] == undefined)
lookup_kana[s.reb] = [i];
else
lookup_kana[s.reb].push(i);
}
}
for (let i = 0; i < 5; i++)
{
console.log(dict[i]);
}
console.log("built lookup tables");
console.log("size:");
console.log(Object.keys(lookup_kan).length);
console.log(Object.keys(lookup_kana).length);
console.log("dict size:");
console.log(dict.length);
// In JMdict, part-of-speech tags are XML entities.
// We processed JMdict's XML with entity processing disabled so we can just use the bare tags (e.g. "v1", not "ichidan verb").
// This left the entity syntax &this; behind so we want to cut it off when we return results.
function clip(str)
{
if(str == undefined)
return;
if(str.length <= 2)
return "";
return str.substring(1, str.length-1);
}
function getfromdict(indexes)
{
let ret = [];
for(let i = 0; i < indexes.length; i++)
{
let entry = dict[indexes[i]];
let lastpos = [];
// JMdict tags part-of-speech for senses sparsely
// e.g. if 1. and 2. share the same list of POSs, only 1. will have a POS list
// undoing this here makes things in the content script WAY less inconvenient
for(let j = 0; j < entry.sense.length; j++)
{
if(entry.sense[j].pos)
{
for(let t = 0; t < entry.sense[j].pos.length; t++)
{
if(entry.sense[j].pos[t].charAt(0)=="&")
entry.sense[j].pos[t] = clip(entry.sense[j].pos[t]);
}
}
else
entry.sense[j].pos = lastpos;
lastpos = entry.sense[j].pos;
}
ret.push(entry);
}
return ret;
}
function search(text)
{
if (lookup_kan[text])
{
//console.log("search successful (kanji)");
return getfromdict(lookup_kan[text]);
}
else if (lookup_kana[text])
{
//console.log("search successful (kana)");
return getfromdict(lookup_kana[text]);
}
else
{
//console.log("search failed");
//console.log(text);
return;
}
}
browser.runtime.onMessage.addListener((request, sender, sendResponse) => {
if (request.type == 'search')
{
//console.log("running search");
sendResponse(search(request.text));
}
else
{
//console.log("unhandled request");
//return;
return;
}
});