Add koreaniframe.html.

This commit is contained in:
voussoir 2026-09-03 22:46:42 -07:00
parent 239d9ec4bf
commit c3435d430e
4 changed files with 408 additions and 9 deletions

View file

@ -5,15 +5,38 @@
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
viewBox="0 0 640 640"
height="640"
width="640"
xml:space="preserve"
id="svg1521"
version="1.1"><metadata
version="1.1"
sodipodi:docname="korean.svg"
inkscape:version="0.92.3 (2405546, 2018-03-11)"><sodipodi:namedview
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1"
objecttolerance="10"
gridtolerance="10"
guidetolerance="10"
inkscape:pageopacity="0"
inkscape:pageshadow="2"
inkscape:window-width="1920"
inkscape:window-height="1019"
id="namedview13"
showgrid="false"
inkscape:zoom="5.9"
inkscape:cx="171.84322"
inkscape:cy="215.0187"
inkscape:window-x="-8"
inkscape:window-y="-8"
inkscape:window-maximized="1"
inkscape:current-layer="svg1521" /><metadata
id="metadata1527"><rdf:RDF><cc:Work
rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" /><dc:title></dc:title></cc:Work></rdf:RDF></metadata><defs
rdf:resource="http://purl.org/dc/dcmitype/StillImage" /><dc:title /></cc:Work></rdf:RDF></metadata><defs
id="defs1525" /><rect
style="opacity:1;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
id="rect887"
@ -34,11 +57,12 @@
style="fill:#003478;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.33333325"
d="m 229.53457,259.68949 c -16.6547,24.98097 -9.90497,58.73398 15.07817,75.38868 24.98097,16.6547 58.73398,9.9028 75.38868,-15.07817 16.65253,-24.98097 50.40553,-31.7307 75.3865,-15.07817 24.98097,16.6547 31.73287,50.40771 15.07817,75.38868 -33.3094,49.9641 -100.81325,63.46357 -150.77735,30.15634 C 209.7268,377.15744 196.22517,309.6536 229.53457,259.68949" /><path
style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.33333325"
d="M 154.14648 365.23438 L 139.06836 375.28711 L 166.71094 416.74805 L 171.73828 424.28711 L 199.38086 465.75 L 214.45703 455.69922 L 154.14648 365.23438 z M 131.52734 380.3125 L 116.45312 390.36133 L 144.0957 431.82617 L 159.17188 421.77539 L 131.52734 380.3125 z M 108.91406 395.38672 L 93.835938 405.43945 L 154.14648 495.90625 L 169.22461 485.85352 L 141.58203 444.39062 L 136.55664 436.85156 L 108.91406 395.38672 z M 164.19727 429.31445 L 149.12109 439.36523 L 176.76367 480.82812 L 191.83984 470.77734 L 164.19727 429.31445 z "
id="path1579" /><path
d="m 154.14648,365.23438 -15.07812,10.05273 60.3125,90.46289 15.07617,-10.05078 z m -22.61914,15.07812 -15.07422,10.04883 27.64258,41.46484 15.07618,-10.05078 z m -22.61328,15.07422 -15.078122,10.05273 60.310542,90.4668 15.07813,-10.05273 z m 55.28321,33.92773 -15.07618,10.05078 27.64258,41.46289 15.07617,-10.05078 z"
id="path1579"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cccccccccccccccccccc" /><path
style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.33333325"
d="M 485.85352 144.0957 L 470.77539 154.14844 L 498.41797 195.60938 L 513.49609 185.55859 L 485.85352 144.0957 z M 463.23828 159.17188 L 448.16016 169.22461 L 475.80273 210.6875 L 490.88086 200.63477 L 463.23828 159.17188 z M 440.61914 174.25 L 425.54297 184.30078 L 453.18555 225.76562 L 468.26367 215.71484 L 440.61914 174.25 z M 518.52148 193.09766 L 503.44531 203.14844 L 531.08789 244.61133 L 546.16406 234.56055 L 518.52148 193.09766 z M 495.90625 208.17383 L 480.82812 218.22656 L 508.4707 259.68945 L 523.54883 249.63672 L 495.90625 208.17383 z M 473.28906 223.25391 L 458.21094 233.30469 L 485.85352 274.76758 L 500.93164 264.71484 L 473.28906 223.25391 z "
id="path1591" /><path
id="path1607"
style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.33333325"
d="m 483.34123,221.99559 -10.05284,-15.07817 15.07817,-10.05066 10.05284,15.07817 z" /></svg>
d="m 485.85352,144.0957 -15.07813,10.05274 27.64258,41.46094 15.07812,-10.05079 z m -22.61524,15.07618 -15.07812,10.05273 60.31054,90.46484 15.07813,-10.05273 z m -22.61914,15.07812 -15.07617,10.05078 27.64258,41.46484 15.07812,-10.05078 z m 77.90234,18.84766 -15.07617,10.05078 27.64258,41.46289 15.07617,-10.05078 z m -45.23242,30.15625 -15.07812,10.05078 27.64258,41.46289 15.07812,-10.05274 z"
id="path1591"
inkscape:connector-curvature="0"
sodipodi:nodetypes="ccccccccccccccccccccccccc" /></svg>

Before

Width:  |  Height:  |  Size: 4.7 KiB

After

Width:  |  Height:  |  Size: 4.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 646 B

View file

@ -0,0 +1,76 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
version="1.1"
id="svg4185"
viewBox="0 0 599.99998 599.99998"
height="169.33333mm"
width="169.33333mm"
sodipodi:docname="favicon.svg"
inkscape:version="0.92.3 (2405546, 2018-03-11)">
<sodipodi:namedview
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1"
objecttolerance="10"
gridtolerance="10"
guidetolerance="10"
inkscape:pageopacity="0"
inkscape:pageshadow="2"
inkscape:window-width="1920"
inkscape:window-height="1019"
id="namedview8"
showgrid="false"
inkscape:zoom="1"
inkscape:cx="382.75813"
inkscape:cy="329.53726"
inkscape:window-x="-8"
inkscape:window-y="-8"
inkscape:window-maximized="1"
inkscape:current-layer="svg4185" />
<defs
id="defs4187" />
<metadata
id="metadata4190">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title />
</cc:Work>
</rdf:RDF>
</metadata>
<g
transform="translate(-15.000019,-437.3622)"
id="layer1">
<circle
r="300"
cy="737.36218"
cx="315"
id="path4761"
style="opacity:1;fill:#0e0e0d;fill-opacity:1;stroke:none;stroke-width:0.64400005;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" />
</g>
<g
id="g836"
transform="matrix(1.7243314,0,0,1.7243314,-251.7857,-251.78702)"
style="stroke-width:0.54368895">
<path
d="m 229.53457,259.68949 c 33.30723,-49.96193 100.81325,-63.46357 150.77518,-30.15416 49.96411,33.30723 63.46357,100.81324 30.15634,150.77518 -33.3094,49.9641 -100.81325,63.46357 -150.77735,30.15634 C 209.7268,377.15744 196.22517,309.6536 229.53457,259.68949"
style="fill:#c60c30;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.72491854"
id="path1571"
inkscape:connector-curvature="0" />
<path
d="m 229.53457,259.68949 c -16.6547,24.98097 -9.90497,58.73398 15.07817,75.38868 24.98097,16.6547 58.73398,9.9028 75.38868,-15.07817 16.65253,-24.98097 50.40553,-31.7307 75.3865,-15.07817 24.98097,16.6547 31.73287,50.40771 15.07817,75.38868 -33.3094,49.9641 -100.81325,63.46357 -150.77735,30.15634 C 209.7268,377.15744 196.22517,309.6536 229.53457,259.68949"
style="fill:#003478;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.72491854"
id="path1575"
inkscape:connector-curvature="0" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 2.9 KiB

View file

@ -0,0 +1,299 @@
<!DOCTYPE html>
<html>
<head>
<title>korean</title>
<link rel="icon" href="/koreaniframe/favicon.png" type="image/png"/>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
<style>
:root
{
--color_background_primary: #0e0e0d;
--color_text_primary: #ccc;
--color_text_highlight: #efcc2b;
--color_inlinecodebg: rgba(255, 255, 255, 0.15);
}
*
{
font-family: Verdana, sans-serif;
color: var(--color_text_primary);
word-break: break-word;
}
html
{
position: relative;
/*height: 100vh;*/
box-sizing: border-box;
}
*, *:before, *:after { box-sizing: inherit; }
body
{
position: relative;
min-height: 100%;
background-color: var(--color_background_primary);
margin: 0;
display: grid;
grid-auto-rows: max-content;
grid-row-gap: 8px;
}
code { font-family: monospace; }
#search_holder
{
justify-self: stretch;
/*width: 98%;*/
max-width:400px;
margin: auto;
padding: 32px;
display: grid;
grid-auto-flow: column;
grid-template-columns: 1fr max-content;
}
#search_input, #search_button
{
font-size:16pt;
}
#search_input
{
width: 100%;
border: 1px solid #444;
background-color: var(--color_background_primary);
}
#search_button
{
background-color: var(--color_background_primary);
border: 1px solid #444;
/*color: var(--color_text_highlight);*/
}
details
{
min-width: 0;
justify-self: stretch;
}
details[open]
{
height: 95vh;
}
summary
{
position: relative;
font-size: 16pt;
margin-left: 10%;
margin-right: 10%;
}
summary a
{
position: absolute;
right: 0;
top: 0;
bottom: 0;
display: flex;
align-items: center;
text-decoration: none;
font-size:12pt;
}
iframe
{
justify-self: stretch;
display: block;
min-width: 0;
height: 90vh;
border: 1px solid #444;
box-sizing: border-box;
}
#whatisthis_button
{
position: absolute;
top: 8px;
right: 8px;
background-color: transparent;
border: none;
cursor: pointer;
}
#whatisthis_dialog
{
border: 1px solid var(--color_text_highlight);
background-color: var(--color_background_primary);
width: 90%;
max-width: 32em;
border-radius: 8px;
padding:8px;
}
</style>
</head>
<body>
<div id="search_holder">
<input type="text" id="search_input" onblur="return set_query_from_input();"/><!--
--><button id="search_button" onclick="return set_query_from_input();">검색</button>
</div>
<details id="details_koendict" data-urltemplate="https://korean.dict.naver.com/koendict/#/search?query={query}">
<summary><span>한영사전</span><a>🔗</a></summary>
</details>
<details id="details_kokodict" data-urltemplate="https://ko.dict.naver.com/#/search?query={query}">
<summary><span>국어사전</span><a>🔗</a></summary>
</details>
<details id="details_hanjadict" data-urltemplate="https://hanja.dict.naver.com/search/?mflag=1&query={query}">
<summary><span>한자사전</span><a>🔗</a></summary>
</details>
<details id="details_images" data-urltemplate="https://www.bing.com/images/search?q={query}">
<summary><span>이미지</span><a>🔗</a></summary>
</details>
<details id="details_papago" data-urltemplate="https://papago.naver.com/?sl=ko&tl=en&text={query}">
<summary><span>파파고</span><a>🔗</a></summary>
</details>
<button id="whatisthis_button" popovertarget="whatisthis_dialog">?</button>
<dialog id="whatisthis_dialog" popover>
<h2>이거 뭔대?</h2>
<p>This page provides iframes to a few of Naver's dictionaries so that I can cross-reference them without opening multiple tabs or going back and forth.</p>
<p>The image search frame is Bing because both Naver and Google block iframes on their search domain. ㅠㅠ</p>
<p>My Anki cards contain a link to this page so I can research a word while studying.</p>
</dialog>
</body>
<script type="text/javascript">
let QUERY;
function set_query_from_input()
{
const input = document.getElementById("search_input");
const new_query = input.value.trim();
// Added the 100ms timeout because if I blur immediately or with a zero
// timeout, the word currently being composed in the IME becomes duplicated
// in the input box on Android.
setTimeout(() => {input.blur()}, 100);
set_query(new_query);
}
function set_query(new_query)
{
new_query = (new_query || "").trim();
if (new_query === QUERY)
{
return;
}
console.log("New query: " + QUERY);
const input = document.getElementById("search_input");
QUERY = new_query;
input.value = QUERY;
if (QUERY !== "")
{
document.title = QUERY;
}
else
{
document.title = "korean";
}
const params = new URLSearchParams();
params.set("q", QUERY);
const newurl = window.location.origin + window.location.pathname + "?" + params.toString();
window.history.replaceState(null, document.title, newurl);
for (const details of Array.from(document.getElementsByTagName("details")))
{
details.dataset.url = details.dataset.urltemplate.replace("{query}", QUERY);
const anchor = details.querySelector("summary a");
anchor.href = details.dataset.url;
make_iframe(details);
}
reset_iframes();
}
function reset_iframes()
{
for (const iframe of Array.from(document.getElementsByTagName("iframe")))
{
if (iframe.closest("details").dataset.persistent)
{
continue;
}
iframe.remove();
}
for (const details of Array.from(document.getElementsByTagName("details")))
{
make_iframe(details);
}
}
function make_iframe(details)
{
if (! details.open)
{
return;
}
if (details.getElementsByTagName("iframe").length > 0)
{
return;
}
if (QUERY === "")
{
return;
}
const iframe = document.createElement("iframe");
iframe.src = details.dataset.url;
details.append(iframe);
}
function bind_box_to_button(box, button, ctrl_enter)
{
/*
Bind a textbox to a button so that pressing Enter within the textbox is the
same as clicking the button.
If `ctrl_enter` is true, then you must press ctrl+Enter to trigger the
button, which is important for textareas.
Thanks Yaroslav Yakovlev
http://stackoverflow.com/a/9343095
*/
const bound_box_hook = function(event)
{
if (event.key !== "Enter")
{return;}
ctrl_success = !ctrl_enter || (event.ctrlKey);
if (! ctrl_success)
{return;}
button.click();
}
box.addEventListener("keyup", bound_box_hook);
}
function details_ontoggle(event)
{
make_iframe(event.target.closest("details"));
}
function on_pageload()
{
const params = new URLSearchParams(window.location.search);
set_query(params.get("q"));
const input = document.getElementById("search_input");
const button = document.getElementById("search_button");
bind_box_to_button(input, button);
for (const details of document.getElementsByTagName("details"))
{
details.addEventListener("toggle", details_ontoggle);
}
}
document.addEventListener("DOMContentLoaded", on_pageload);
</script>
</html>