Add a built in reader page with a clipboard hook
This commit is contained in:
1 parent
a04abfde27
commit
41cc30b9f1
7 files changed
+210
-33
No files matched your search
+43
-14
@@ -741,18 +741,6 @@ function lookup_indirect(text, time)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
browser.runtime.onMessage.addListener((req, sender, sendResponse) =>
|
|
||||||
{
|
|
||||||
if (req.type == "search")
|
|
||||||
{
|
|
||||||
sendResponse(lookup_indirect(req.text, req.time));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
async function update_icon(enabled)
|
async function update_icon(enabled)
|
||||||
{
|
{
|
||||||
if(enabled)
|
if(enabled)
|
||||||
@@ -783,16 +771,57 @@ async function toggle_enabled()
|
|||||||
update_icon(enabled);
|
update_icon(enabled);
|
||||||
}
|
}
|
||||||
|
|
||||||
async function init_icon()
|
async function fixicon()
|
||||||
{
|
{
|
||||||
browser.browserAction.onClicked.addListener(toggle_enabled);
|
|
||||||
let enabled = (await browser.storage.local.get("enabled")).enabled;
|
let enabled = (await browser.storage.local.get("enabled")).enabled;
|
||||||
if(enabled == undefined)
|
if(enabled == undefined)
|
||||||
enabled = false;
|
enabled = false;
|
||||||
update_icon(enabled);
|
update_icon(enabled);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function init_icon()
|
||||||
|
{
|
||||||
|
browser.browserAction.onClicked.addListener(toggle_enabled);
|
||||||
|
fixicon();
|
||||||
|
}
|
||||||
|
|
||||||
init_icon();
|
init_icon();
|
||||||
|
|
||||||
|
function tryopenwindow(info, tab)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
browser.windows.create({
|
||||||
|
url:browser.extension.getURL("reader.html"),
|
||||||
|
type:"popup"
|
||||||
|
});
|
||||||
|
}
|
||||||
|
catch(err)
|
||||||
|
{
|
||||||
|
console.log(err);
|
||||||
|
console.log(JSON.stringify(err, Object.getOwnPropertyNames(err)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
browser.contextMenus.create({
|
||||||
|
id: "nazeka-reopen",
|
||||||
|
title: "Open Reader",
|
||||||
|
contexts: ["browser_action"],
|
||||||
|
onclick: tryopenwindow
|
||||||
|
});
|
||||||
|
|
||||||
|
browser.runtime.onMessage.addListener((req, sender, sendResponse) =>
|
||||||
|
{
|
||||||
|
if (req.type == "search")
|
||||||
|
{
|
||||||
|
sendResponse(lookup_indirect(req.text, req.time));
|
||||||
|
}
|
||||||
|
else if (req.type == "toggle")
|
||||||
|
{
|
||||||
|
toggle_enabled();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
});
|
||||||
+6
-2
@@ -5,7 +5,9 @@
|
|||||||
|
|
||||||
"permissions": [
|
"permissions": [
|
||||||
"contextMenus",
|
"contextMenus",
|
||||||
"storage"
|
"storage",
|
||||||
|
"tabs",
|
||||||
|
"clipboardRead"
|
||||||
],
|
],
|
||||||
|
|
||||||
"background": {
|
"background": {
|
||||||
@@ -13,7 +15,9 @@
|
|||||||
},
|
},
|
||||||
|
|
||||||
"web_accessible_resources": [
|
"web_accessible_resources": [
|
||||||
"dict/JMdict.json"
|
"dict/JMdict.json",
|
||||||
|
"reader.js",
|
||||||
|
"reader.html"
|
||||||
],
|
],
|
||||||
|
|
||||||
"content_scripts": [
|
"content_scripts": [
|
||||||
|
|||||||
+3
-1
@@ -12,7 +12,9 @@
|
|||||||
<div class="panel-section panel-section-formElements browser-style">
|
<div class="panel-section panel-section-formElements browser-style">
|
||||||
<input id="enabled" type="checkbox" name=enabled class=panel-formElements-item/><label for=enabled class=panel-formElements-item>Enabled</label>
|
<input id="enabled" type="checkbox" name=enabled class=panel-formElements-item/><label for=enabled class=panel-formElements-item>Enabled</label>
|
||||||
<input id="compact" type="checkbox" name=compact class=panel-formElements-item/><label for=compact class=panel-formElements-item>Compact</label>
|
<input id="compact" type="checkbox" name=compact class=panel-formElements-item/><label for=compact class=panel-formElements-item>Compact</label>
|
||||||
<input id="length" type="number" min="6" max="100" value="25" name=length class=panel-formElements-item/><label for=length class=panel-formElements-item>Search length (characters) (default 25, sane values are from 25 and 50)</label>
|
<input id="fixedwidth" type="checkbox" name=fixedwidth class=panel-formElements-item/><label for=fixedwidth class=panel-formElements-item>Fixed width</label>
|
||||||
|
<input id="fixedwidthpositioning" type="checkbox" name=fixedwidthpositioning class=panel-formElements-item/><label for=fixedwidthpositioning class=panel-formElements-item>Position as though fixed width</label>
|
||||||
|
<input id="length" type="number" min="6" max="100" value="25" name=length class=panel-formElements-item/><label for=length class=panel-formElements-item>Search length (characters) (default 25, sane values are from 25 to 50)</label>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
+14
@@ -3,12 +3,16 @@ function restoreListeners()
|
|||||||
document.querySelector("#enabled").addEventListener("change", setOptions);
|
document.querySelector("#enabled").addEventListener("change", setOptions);
|
||||||
document.querySelector("#compact").addEventListener("change", setOptions);
|
document.querySelector("#compact").addEventListener("change", setOptions);
|
||||||
document.querySelector("#length").addEventListener("change", setOptions);
|
document.querySelector("#length").addEventListener("change", setOptions);
|
||||||
|
document.querySelector("#fixedwidth").addEventListener("change", setOptions);
|
||||||
|
document.querySelector("#fixedwidthpositioning").addEventListener("change", setOptions);
|
||||||
}
|
}
|
||||||
function removeListeners()
|
function removeListeners()
|
||||||
{
|
{
|
||||||
document.querySelector("#enabled").removeEventListener("change", setOptions);
|
document.querySelector("#enabled").removeEventListener("change", setOptions);
|
||||||
document.querySelector("#compact").removeEventListener("change", setOptions);
|
document.querySelector("#compact").removeEventListener("change", setOptions);
|
||||||
document.querySelector("#length").removeEventListener("change", setOptions);
|
document.querySelector("#length").removeEventListener("change", setOptions);
|
||||||
|
document.querySelector("#fixedwidth").removeEventListener("change", setOptions);
|
||||||
|
document.querySelector("#fixedwidthpositioning").removeEventListener("change", setOptions);
|
||||||
}
|
}
|
||||||
|
|
||||||
async function restoreOptions()
|
async function restoreOptions()
|
||||||
@@ -24,10 +28,18 @@ async function restoreOptions()
|
|||||||
let length = (await browser.storage.local.get("length")).length;
|
let length = (await browser.storage.local.get("length")).length;
|
||||||
if(length == undefined)
|
if(length == undefined)
|
||||||
length = 25;
|
length = 25;
|
||||||
|
let fixedwidth = (await browser.storage.local.get("fixedwidth")).fixedwidth;
|
||||||
|
if(fixedwidth == undefined)
|
||||||
|
fixedwidth = false;
|
||||||
|
let fixedwidthpositioning = (await browser.storage.local.get("fixedwidthpositioning")).fixedwidthpositioning;
|
||||||
|
if(fixedwidthpositioning == undefined)
|
||||||
|
fixedwidthpositioning = false;
|
||||||
removeListeners();
|
removeListeners();
|
||||||
document.querySelector("#enabled").checked = enabled?true:false;
|
document.querySelector("#enabled").checked = enabled?true:false;
|
||||||
document.querySelector("#compact").checked = compact?true:false;
|
document.querySelector("#compact").checked = compact?true:false;
|
||||||
document.querySelector("#length").value = length?length:25;
|
document.querySelector("#length").value = length?length:25;
|
||||||
|
document.querySelector("#fixedwidth").checked = fixedwidth?true:false;
|
||||||
|
document.querySelector("#fixedwidthpositioning").checked = fixedwidthpositioning?true:false;
|
||||||
}
|
}
|
||||||
catch (error){}
|
catch (error){}
|
||||||
removeListeners();
|
removeListeners();
|
||||||
@@ -44,6 +56,8 @@ function setOptions()
|
|||||||
enabled: document.querySelector("#enabled").checked,
|
enabled: document.querySelector("#enabled").checked,
|
||||||
compact: document.querySelector("#compact").checked,
|
compact: document.querySelector("#compact").checked,
|
||||||
length: length,
|
length: length,
|
||||||
|
fixedwidth: document.querySelector("#fixedwidth").checked,
|
||||||
|
fixedwidthpositioning: document.querySelector("#fixedwidthpositioning").checked,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+26
@@ -0,0 +1,26 @@
|
|||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<title>Text Grabber</title>
|
||||||
|
<style>
|
||||||
|
body
|
||||||
|
{
|
||||||
|
background-color: #111;
|
||||||
|
color: #CCC;
|
||||||
|
font-family: Verdana, Arial, IPAGothic, TakaoGothic, Noto Sans CJK JP Regular, Meiryo, sans-serif;
|
||||||
|
font-size: 1.4em;
|
||||||
|
}
|
||||||
|
html
|
||||||
|
{
|
||||||
|
overflow-y: scroll;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
<script src="reader.js"></script>
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body lang="ja">
|
||||||
|
<p id="helptext"><i>This page grabs from the clipboard automatically if it contains Japanese text. If this page is not opened, Nazeka will never access the clipboard.</i></p>
|
||||||
|
<p><i>Use the context menu (right click the page) to toggle Nazeka.</i></p>
|
||||||
|
<div style="position:absolute;visibility:hidden"><textarea id="nazeka-paste-target"></textarea></div>
|
||||||
|
</body>
|
||||||
|
|
||||||
|
</html>
|
||||||
@@ -0,0 +1,74 @@
|
|||||||
|
function toggle()
|
||||||
|
{
|
||||||
|
browser.runtime.sendMessage({type:"toggle"});
|
||||||
|
}
|
||||||
|
|
||||||
|
browser.contextMenus.create({
|
||||||
|
id: "nazeka-toggle",
|
||||||
|
title: "Toggle Nazeka",
|
||||||
|
contexts: ["all"],
|
||||||
|
onclick: toggle
|
||||||
|
});
|
||||||
|
|
||||||
|
function might_have_japanese(text)
|
||||||
|
{
|
||||||
|
for(let char of text)
|
||||||
|
if(char && char.length > 0 && char.codePointAt(0) > 0x2E80)
|
||||||
|
return true;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
function update(text)
|
||||||
|
{
|
||||||
|
if(!might_have_japanese(text))
|
||||||
|
return;
|
||||||
|
|
||||||
|
let target = document.body;
|
||||||
|
let newnode = document.createElement("p");
|
||||||
|
newnode.textContent = text;
|
||||||
|
|
||||||
|
target.insertBefore(newnode, document.querySelector("#helptext"));
|
||||||
|
}
|
||||||
|
|
||||||
|
let text_previous = "";
|
||||||
|
function cycle_text(text)
|
||||||
|
{
|
||||||
|
if(text != "" && text != text_previous)
|
||||||
|
update(text);
|
||||||
|
text_previous = text;
|
||||||
|
}
|
||||||
|
|
||||||
|
window.addEventListener("load", () =>
|
||||||
|
{
|
||||||
|
document.querySelector("#nazeka-paste-target").addEventListener("paste", (event) =>
|
||||||
|
{
|
||||||
|
// skip event if there's no plaintext; thanks github.com/kmltml/clipboard-inserter
|
||||||
|
let text = event.clipboardData.getData("text/plain");
|
||||||
|
if(text !== "")
|
||||||
|
cycle_text(text);
|
||||||
|
|
||||||
|
event.preventDefault();
|
||||||
|
})
|
||||||
|
});
|
||||||
|
|
||||||
|
function checkpaste()
|
||||||
|
{
|
||||||
|
let target = document.querySelector("#nazeka-paste-target");
|
||||||
|
|
||||||
|
target.parentNode.style.visibility = "visible";
|
||||||
|
|
||||||
|
target.textContent = "";
|
||||||
|
target.focus();
|
||||||
|
document.execCommand("paste");
|
||||||
|
|
||||||
|
target.parentNode.style.visibility = "hidden";
|
||||||
|
}
|
||||||
|
|
||||||
|
let interval = 250;
|
||||||
|
|
||||||
|
setInterval(checkpaste, interval);
|
||||||
|
|
||||||
|
var executing = browser.tabs.executeScript({
|
||||||
|
file: "/texthook.js",
|
||||||
|
allFrames: true
|
||||||
|
});
|
||||||
+44
-16
@@ -26,6 +26,8 @@ let settings = {
|
|||||||
enabled: false,
|
enabled: false,
|
||||||
compact: true,
|
compact: true,
|
||||||
length: 25,
|
length: 25,
|
||||||
|
fixedwidth: false,
|
||||||
|
fixedwidthpositioning: false,
|
||||||
};
|
};
|
||||||
|
|
||||||
let last_time_display = Date.now();
|
let last_time_display = Date.now();
|
||||||
@@ -45,6 +47,9 @@ function delete_div ()
|
|||||||
|
|
||||||
function display_div (middle, x, y, time)
|
function display_div (middle, x, y, time)
|
||||||
{
|
{
|
||||||
|
middle.style = "background-color: #111; border-radius: 2.5px; border: 1px solid #111;";
|
||||||
|
middle.firstChild.style = "border: 1px solid white; border-radius: 2px; padding: 2px; background-color: #111; color: #CCC; font-family: Arial, sans-serif; font-size: 13px; text-align: left;";
|
||||||
|
|
||||||
let find_root = window;
|
let find_root = window;
|
||||||
let newx = x;
|
let newx = x;
|
||||||
let newy = y;
|
let newy = y;
|
||||||
@@ -59,32 +64,49 @@ function display_div (middle, x, y, time)
|
|||||||
}
|
}
|
||||||
let mydoc = find_root.document;
|
let mydoc = find_root.document;
|
||||||
|
|
||||||
middle.style = "background-color: #111; border-radius: 2.5px; border: 1px solid #111;";
|
let styletext = "";
|
||||||
middle.firstChild.style = "border: 1px solid white; border-radius: 2px; padding: 2px; background-color: #111; color: #CCC; font-family: Arial, sans-serif; font-size: 13px; text-align: left;";
|
if(settings.fixedwidth)
|
||||||
|
styletext += "width: 600px; "
|
||||||
|
else
|
||||||
|
styletext += "max-width: 600px; "
|
||||||
|
styletext += "position: absolute; top: 0; left: 0;";
|
||||||
|
styletext += "background-color: white; border-radius: 3px; border: 1px solid white; z-index: 100000;";
|
||||||
|
|
||||||
let other = mydoc.body.getElementsByClassName(div_class);
|
let other = mydoc.body.getElementsByClassName(div_class);
|
||||||
|
let outer = undefined;
|
||||||
if(other.length > 0)
|
if(other.length > 0)
|
||||||
{
|
{
|
||||||
other[0].replaceChild(middle, other[0].firstChild);
|
outer = other[0];
|
||||||
|
outer.replaceChild(middle, other[0].firstChild);
|
||||||
let styletext = "max-width: 600px; position: absolute; top: " + (newy+5) + "px; left: " + (newx+5) + "px;";
|
outer.style.visibility = "visible";
|
||||||
styletext += "background-color: white; border-radius: 3px; border: 1px solid white; z-index: 100000;";
|
|
||||||
other[0].style = styletext;
|
|
||||||
|
|
||||||
other[0].style.visibility = "visible";
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
let outer = mydoc.createElement("div");
|
outer = mydoc.createElement("div");
|
||||||
outer.className = div_class;
|
outer.className = div_class;
|
||||||
let styletext = "max-width: 600px; position: absolute; top: " + (newy+5) + "px; left: " + (newx+5) + "px;";
|
|
||||||
styletext += "background-color: white; border-radius: 3px; border: 1px solid white; z-index: 100000;";
|
|
||||||
outer.style = styletext;
|
|
||||||
|
|
||||||
outer.appendChild(middle);
|
outer.appendChild(middle);
|
||||||
|
|
||||||
mydoc.body.appendChild(outer);
|
mydoc.body.appendChild(outer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
outer.style = styletext;
|
||||||
|
|
||||||
|
|
||||||
|
let mywidth = 600;
|
||||||
|
if(!settings.fixedwidthpositioning)
|
||||||
|
mywidth = outer.offsetWidth;
|
||||||
|
|
||||||
|
let buffer = 25;
|
||||||
|
let pretend_doc_width = Math.max(mywidth, mydoc.defaultView.innerWidth);
|
||||||
|
if(newx + mywidth > pretend_doc_width)
|
||||||
|
{
|
||||||
|
newx -= (newx + mywidth - pretend_doc_width);
|
||||||
|
newx -= buffer;
|
||||||
|
if(newx < 0)
|
||||||
|
newx = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
outer.style.top = (newy+5)+"px";
|
||||||
|
outer.style.left = (newx+5)+"px";
|
||||||
}
|
}
|
||||||
|
|
||||||
function exists_div()
|
function exists_div()
|
||||||
@@ -455,6 +477,12 @@ async function settings_reload()
|
|||||||
settings.length = (await browser.storage.local.get("length")).length;
|
settings.length = (await browser.storage.local.get("length")).length;
|
||||||
if(!settings.length)
|
if(!settings.length)
|
||||||
settings.length = 25;
|
settings.length = 25;
|
||||||
|
settings.fixedwidth = (await browser.storage.local.get("fixedwidth")).fixedwidth;
|
||||||
|
if(!settings.fixedwidth)
|
||||||
|
settings.fixedwidth = false;
|
||||||
|
settings.fixedwidthpositioning = (await browser.storage.local.get("fixedwidthpositioning")).fixedwidthpositioning;
|
||||||
|
if(!settings.fixedwidthpositioning)
|
||||||
|
settings.fixedwidthpositioning = false;
|
||||||
|
|
||||||
if(!settings.enabled && exists_div())
|
if(!settings.enabled && exists_div())
|
||||||
delete_div();
|
delete_div();
|
||||||
@@ -464,7 +492,7 @@ async function settings_reload()
|
|||||||
}
|
}
|
||||||
catch(error)
|
catch(error)
|
||||||
{
|
{
|
||||||
console.log("failed to set settings, maybe not stored yet?");
|
//console.log("failed to set settings, maybe not stored yet?");
|
||||||
} // not stored yet, probably
|
} // not stored yet, probably
|
||||||
|
|
||||||
settings_reloader = setTimeout(settings_reload, settings_reload_rate);
|
settings_reloader = setTimeout(settings_reload, settings_reload_rate);
|
||||||
|
|||||||
Reference in new issue
Block a user