finish implementing json dictionary manager

This commit is contained in:
wareya committed 2019-05-13 23:53:47 -04:00
1 parent 2d80feeae9
commit 74165046e3
3 files changed
+277 -14

No files matched your search

+3 -2
View File
@@ -84,7 +84,7 @@ async function get_storage_or_default(name, fallback)
async function refresh_json() async function refresh_json()
{ {
let custom_dicts = (await get_storage_or_default("custom_dicts", [])); let custom_dicts = (await get_storage_or_default("custom_dicts", []));
json_dicts = []; let new_json_dicts = [];
for(let stored_dict of custom_dicts) for(let stored_dict of custom_dicts)
{ {
if(!stored_dict.enabled) if(!stored_dict.enabled)
@@ -103,8 +103,9 @@ async function refresh_json()
add_json_spelling(dict, spelling, i); add_json_spelling(dict, spelling, i);
} }
} catch(e){} } catch(e){}
json_dicts.push(dict); new_json_dicts.push(dict);
} }
json_dicts = new_json_dicts;
} }
async function migrate_legacy_then_refresh() async function migrate_legacy_then_refresh()
+81 -11
View File
@@ -22,34 +22,104 @@ option.disabled
div.buttons div.buttons
{ {
display:flex; display:flex;
width: 200px; width: 300px;
flex-direction: row; flex-direction: row;
flex-wrap: wrap; flex-wrap: wrap;
justify-content: center; justify-content: center;
} }
div.buttons * div.buttons *
{ {
width: 33%; width: 33.3%;
}
div.buttons button.double
{
width: 50%;
} }
#delete #delete
{ {
margin-top: 20px; margin-top: 20px;
} }
div.closed
{
display: none;
}
</style> </style>
<script src="include/browser-polyfill.min.js" charset="UTF-8"></script> <script src="include/browser-polyfill.min.js" charset="UTF-8"></script>
<script src="json_config.js" charset="UTF-8"></script> <script src="json_config.js" charset="UTF-8"></script>
</head> </head>
<body lang="ja" visible="5"> <body lang="ja" visible="5">
<select id=dicts size="10" style="width: 200px; box-sizing: border-box; border: none;"> <div id=dict_manager>
<option value="wadai">Kenkyuusha/Wadai</option> <select id=dicts size="10" style="width: 300px; box-sizing: border-box; border: none;">
<option value="shinmeikai">Shinmeikai</option> <option class=disabled>ローディング中</option>
<option value="muramasa">Muramasa</option> </select>
</select> <div class=buttons>
<div class=buttons> <button id=move_up>Move Up</button><button id=move_down>Move Down</button><button id=toggle>Toggle</button>
<button id=move_up>Move Up</button><button id=move_down>Move Down</button><button id=add disabled>Add Blank</button> <button id=import class=double>Import</button><button id=export class=double>Export</button>
<button id=import disabled>Import</button><button id=toggle>Toggle</button><button id=edit disabled>Edit</button> <button id=add class=double>Add Blank</button><button id=edit class=double>Edit</button>
<button id=delete disabled>Delete</button></div> <button id=delete>Delete</button>
</div>
<input type=file id=file_input style="display: none">
</div>
<div id=dict_editor class=closed>
<input type=text id=edit_name value="" style="width: 300px"><button id=edit_apply>Apply</button><button id=edit_okay>Apply &amp; Close</button><button id=edit_cancel>Close</button>
<textarea type=text id=edit_entries value="" style="width: 100%; height:calc(100vh - 200px)"></textarea>
<div class=edit_explanation>
<pre>
Format (copy-paste-able):
[
{
"r": "つるぎ",
"s": [
""
],
"l": [
"line one of a definition",
"line two of a definition",
"etc",
"last line of a definition"
]
},
{
"r": "こだいしゅ",
"s": [
"古代種",
"古代しゅ"
],
"l": [
"the ancients"
]
}
]
Format (with comments, which break JSON parsing):
[
{ // entry one
"r": "つるぎ",
"s": [
"" // entries with no "spellings" still have a single, blank spelling
], // comma
"l": [
"line one of a definition",
"line two of a definition",
"etc",
"last line of a definition" // no comma
]
}, // comma
{ // entry two
"r": "こだいしゅ",
"s": [
"古代種",
"古代しゅ" // no comma
], // comma
"l": [
"the ancients" // no comma
]
} // last entry, so no comma
]
</pre>
</div>
</div>
</body> </body>
</html> </html>
+193 -1
View File
@@ -52,6 +52,91 @@ function toggle()
save_dicts(); save_dicts();
} }
function add_blank()
{
dicts.push({"name": "Unnamed", "entries": "[]", "enabled": true});
let list = document.getElementById("dicts");
let option = document.createElement("option");
option.innerText = "Unnamed";
option.value = "Unnamed";
list.appendChild(option);
save_dicts();
}
function errormessage(text)
{
if(!text) return;
let mydiv = document.createElement("div");
mydiv.style = "background-color: #111; color: #CCC; font-family: Arial, sans-serif; font-size: 13px; width: 300px; border: 3px double red; position: fixed; right: 25px; top: 25px; z-index: 1000000000000000000000; padding: 5px; border-radius: 3px;"
mydiv.textContent = text;
document.body.appendChild(mydiv);
function delete_later()
{
mydiv.remove();
}
setTimeout(delete_later, 3000);
}
function edit()
{
let list = document.getElementById("dicts");
let index = list.selectedIndex;
if(index == -1)
return;
if(dicts[index].entries.length > 100*1000)
{
errormessage("This dictionary is too large to edit within your web browser.");
return;
}
let name = dicts[index].name;
let entries = JSON.stringify(JSON.parse(dicts[index].entries), null, 2);
console.log(entries);
document.getElementById("dict_manager").className = "closed";
document.getElementById("dict_editor").className = "";
document.getElementById("edit_name").value = name;
document.getElementById("edit_entries").value = entries;
}
function edit_cancel()
{
document.getElementById("dict_manager").className = "";
document.getElementById("dict_editor").className = "closed";
document.getElementById("edit_entries").value = "";
}
function edit_apply()
{
try
{
let list = document.getElementById("dicts");
let index = list.selectedIndex;
if(index != -1)
{
let new_name = document.getElementById("edit_name").value;
let new_json = JSON.stringify(JSON.parse(document.getElementById("edit_entries").value));
dicts[index].name = new_name;
dicts[index].entries = new_json;
list[index].value = new_name;
list[index].innerText = new_name;
save_dicts();
}
}
catch(e)
{
errormessage(e);
}
}
function edit_okay()
{
edit_apply();
edit_cancel();
}
function or_default(val, fallback) function or_default(val, fallback)
{ {
@@ -68,9 +153,9 @@ async function get_storage_or_default(name, fallback)
async function insert_dicts() async function insert_dicts()
{ {
let list = document.getElementById("dicts"); let list = document.getElementById("dicts");
list.innerHTML = "";
dicts = (await get_storage_or_default("custom_dicts", [])); dicts = (await get_storage_or_default("custom_dicts", []));
list.innerHTML = "";
for(let stored_dict of dicts) for(let stored_dict of dicts)
{ {
@@ -83,11 +168,118 @@ async function insert_dicts()
} }
} }
let delete_timeout = undefined;
function really_delete()
{
console.log("on REALLY delete");
set_base_delete_mode();
let list = document.getElementById("dicts");
let index = list.selectedIndex;
if(index == -1)
return;
console.log("gonna delete it!");
dicts.splice(index, 1);
list.remove(index);
save_dicts();
}
function ask_delete()
{
document.getElementById("delete").onclick = really_delete;
document.getElementById("delete").innerText = "REALLY Delete";
delete_timeout = setTimeout(set_base_delete_mode, 5000);
}
function set_base_delete_mode()
{
try
{
clearTimeout(delete_timeout);
} catch(e) {}
delete_timeout = undefined;
document.getElementById("delete").onclick = ask_delete;
document.getElementById("delete").innerText = "Delete";
}
function import_new()
{
document.getElementById("file_input").click();
}
function export_dict()
{
let list = document.getElementById("dicts");
let index = list.selectedIndex;
if(index == -1)
return;
let name = dicts[index].name;
let obj = JSON.parse(dicts[index].entries);
obj.unshift(name);
let blob = new Blob([JSON.stringify(obj, null, 2)], {type: 'text/plain'});
let url = window.URL.createObjectURL(blob);
let a = document.createElement("a");
a.href = url;
a.download = "nazeka_dict_export_"+name+".json";
document.body.appendChild(a);
a.click();
document.body.removeChild(a);
window.URL.revokeObjectURL(url);
}
function buildpage() function buildpage()
{ {
document.getElementById("move_up").onclick = move_up; document.getElementById("move_up").onclick = move_up;
document.getElementById("move_down").onclick = move_down; document.getElementById("move_down").onclick = move_down;
document.getElementById("toggle").onclick = toggle; document.getElementById("toggle").onclick = toggle;
document.getElementById("add").onclick = add_blank;
document.getElementById("edit").onclick = edit;
document.getElementById("delete").onclick = ask_delete;
document.getElementById("edit_apply").onclick = edit_apply;
document.getElementById("edit_okay").onclick = edit_okay;
document.getElementById("edit_cancel").onclick = edit_cancel;
document.getElementById("import").onclick = import_new;
document.getElementById("export").onclick = export_dict;
document.getElementById("file_input").onchange = () =>
{
let fname = document.getElementById("file_input").files[0];
let reader = new FileReader();
reader.onload = async(e) =>
{
// FIXME: add asking for the unlimited storage permission
try
{
let myobj = JSON.parse(e.target.result);
let name = myobj.shift();
dicts.push({"name": name, "entries": JSON.stringify(myobj), "enabled": true});
let option = document.createElement("option");
option.innerText = name;
option.value = name;
let list = document.getElementById("dicts");
list.appendChild(option);
save_dicts();
}
catch(e)
{
errormessage(e);
}
};
reader.readAsText(fname);
};
insert_dicts(); insert_dicts();
} }