aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorlonkaars <loek@pipeframe.xyz>2023-01-29 22:29:48 +0100
committerlonkaars <loek@pipeframe.xyz>2023-01-29 22:29:48 +0100
commit97b6e373ba2f654dadd9c299c09098879de964fc (patch)
treee0af41a66b133470394e34085dda61a21268ef1f
parent2f74b3659b3aac4bd9bccee705f1b972a5332f4d (diff)
add copy button for copying word to custom card template
-rw-r--r--yomichan-user/conf.d/lib.js44
-rw-r--r--yomichan-user/conf.d/sentence-export.js38
-rw-r--r--yomichan-user/conf.d/word-export.css2
-rw-r--r--yomichan-user/conf.d/word-export.css.m42
-rw-r--r--yomichan-user/conf.d/word-export.js68
-rw-r--r--yomichan-user/copy-bitmap.svg50
-rw-r--r--yomichan-user/makefile7
7 files changed, 175 insertions, 36 deletions
diff --git a/yomichan-user/conf.d/lib.js b/yomichan-user/conf.d/lib.js
new file mode 100644
index 0000000..6cb231e
--- /dev/null
+++ b/yomichan-user/conf.d/lib.js
@@ -0,0 +1,44 @@
+async function getClipboardSettings() {
+ return (await yomichan.api.getSettings([{
+ scope: "profile",
+ optionsContext: { current: true },
+ path: 'clipboard'
+ }]))[0].result;
+}
+
+async function setClipboardSettings(settings) {
+ await yomichan.api.modifySettings([{
+ scope: "profile",
+ optionsContext: { current: true },
+ path: 'clipboard',
+ action: 'set',
+ value: settings
+ }]);
+}
+
+async function escapeYomichanCopy(text) {
+ var userClipboardSettings = await getClipboardSettings();
+ var tempSettings = {
+ enableBackgroundMonitor: false,
+ enableSearchPageMonitor: false,
+ autoSearchContent: false,
+ maximumSearchLength: userClipboardSettings.maximumSearchLength,
+ };
+ await setClipboardSettings(tempSettings);
+
+ navigator.clipboard.writeText(text);
+
+ // execute on next JS event loop
+ setTimeout(async () => await setClipboardSettings(userClipboardSettings), 0);
+}
+
+function rubyHelper(element, reading) {
+ var out = "";
+ for (var child of element.childNodes) {
+ if (reading && child.nodeName != "RT") continue;
+ if (!reading && child.nodeName == "RT") continue;
+ out += child.innerText;
+ }
+ return out;
+}
+
diff --git a/yomichan-user/conf.d/sentence-export.js b/yomichan-user/conf.d/sentence-export.js
index f15d890..176cdcd 100644
--- a/yomichan-user/conf.d/sentence-export.js
+++ b/yomichan-user/conf.d/sentence-export.js
@@ -1,21 +1,3 @@
-async function getClipboardSettings() {
- return (await yomichan.api.getSettings([{
- scope: "profile",
- optionsContext: { current: true },
- path: 'clipboard'
- }]))[0].result;
-}
-
-async function setClipboardSettings(settings) {
- await yomichan.api.modifySettings([{
- scope: "profile",
- optionsContext: { current: true },
- path: 'clipboard',
- action: 'set',
- value: settings
- }]);
-}
-
async function exportSentence() {
var inputHTML = document.getElementById("query-parser-content");
var output = "";
@@ -42,19 +24,7 @@ async function exportSentence() {
}
}
- var userClipboardSettings = await getClipboardSettings();
- var tempSettings = {
- enableBackgroundMonitor: false,
- enableSearchPageMonitor: false,
- autoSearchContent: false,
- maximumSearchLength: userClipboardSettings.maximumSearchLength,
- };
- await setClipboardSettings(tempSettings);
-
- navigator.clipboard.writeText(output);
-
- // execute on next JS event loop
- setTimeout(async () => await setClipboardSettings(userClipboardSettings), 0);
+ escapeYomichanCopy(output);
return output;
}
@@ -72,13 +42,11 @@ function patchSearchBar() {
searchBarOuter.insertBefore(button, searchBarOuter.childNodes[2]);
}
-function run() {
+(() => {
if (document.body.classList.contains("patched")) return;
patchSearchBar();
document.body.classList.add("patched");
-}
-
-run();
+})();
diff --git a/yomichan-user/conf.d/word-export.css b/yomichan-user/conf.d/word-export.css
new file mode 100644
index 0000000..0ae2eea
--- /dev/null
+++ b/yomichan-user/conf.d/word-export.css
@@ -0,0 +1,2 @@
+.icon[data-icon=copy-bmp] { --icon-image: url(data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMTYiIGhlaWdodD0iMTYiIHZpZXdCb3g9IjAgMCAxNiAxNiIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4KPGcgY2xpcC1wYXRoPSJ1cmwoI2NsaXAwXzFfMjE4KSI+CjxnIGNsaXAtcGF0aD0idXJsKCNjbGlwMV8xXzIxOCkiPgo8cGF0aCBmaWxsLXJ1bGU9ImV2ZW5vZGQiIGNsaXAtcnVsZT0iZXZlbm9kZCIgZD0iTTEyIDRIN1Y3VjE1SDEySDE1VjdIMTJWNFpNMTMgNUgxNFY2SDEzVjVaIiBmaWxsPSJ1cmwoI3BhaW50MF9saW5lYXJfMV8yMTgpIi8+CjxwYXRoIGZpbGwtcnVsZT0iZXZlbm9kZCIgY2xpcC1ydWxlPSJldmVub2RkIiBkPSJNNyAzSDEySDEzVjRIMTRWNUgxNVY2SDE2VjdWMTVWMTZIMTVMNyAxNkg2VjE1VjRWM0g3Wk03IDE1VjRIMTJWNlY3SDEzSDE1VjE1SDdaTTE0IDVIMTNMMTMgNkgxNFY1WiIgZmlsbD0iYmxhY2siLz4KPC9nPgo8ZyBvcGFjaXR5PSIwLjUiIGNsaXAtcGF0aD0idXJsKCNjbGlwMl8xXzIxOCkiPgo8cGF0aCBkPSJNMyAxVjExSDJWMTNIMVYxNUg5VjE0SDExVjEzSDEyVjEySDEzVjVIMTJWNEgxMVYzSDEwVjJIOVYxSDNaIiBmaWxsPSJibGFjayIvPgo8L2c+CjxnIGNsaXAtcGF0aD0idXJsKCNjbGlwM18xXzIxOCkiPgo8cGF0aCBmaWxsLXJ1bGU9ImV2ZW5vZGQiIGNsaXAtcnVsZT0iZXZlbm9kZCIgZD0iTTcgMUgzVjVIMlYxMUgxVjEzSDNINEg3VjExSDExVjVIN1YxWk05IDJIOFYzVjRIOUgxMFYzSDlWMloiIGZpbGw9InVybCgjcGFpbnQxX2xpbmVhcl8xXzIxOCkiLz4KPHBhdGggZD0iTTEwIDEwSDZWMTNIMTBWMTBaIiBmaWxsPSJ1cmwoI3BhaW50Ml9saW5lYXJfMV8yMTgpIi8+CjxwYXRoIGZpbGwtcnVsZT0iZXZlbm9kZCIgY2xpcC1ydWxlPSJldmVub2RkIiBkPSJNNyAwSDNIMlYxVjEwSDNWMUg3VjRWNUg4SDExVjEwSDEwVjEySDExVjExSDEyVjVWNEgxMVYzSDEwVjRIOEw4IDJIOVYxSDhWMEg3Wk05IDJIMTBWM0g5VjJaTTggMTNWMTJIMTBWMTNIOFpNOCAxM1YxNEg0VjEzSDhaTTEgMTJIMlYxMEgxVjEyWk0xIDEySDBWMTRIMVYxMloiIGZpbGw9InVybCgjcGFpbnQzX2xpbmVhcl8xXzIxOCkiLz4KPHBhdGggZmlsbC1ydWxlPSJldmVub2RkIiBjbGlwLXJ1bGU9ImV2ZW5vZGQiIGQ9Ik03IDlIOFYxMEg3VjExVjEySDZWMTNINVYxNEgxVjEzSDRWMTJINVYxMUg2VjEwVjlIN1pNOCAxMEgxMFYxMUg4VjEwWiIgZmlsbD0iIzA2MDcwQSIvPgo8cmVjdCB4PSI0IiB5PSIyIiB3aWR0aD0iMyIgaGVpZ2h0PSIxIiBmaWxsPSIjMDYwNzBBIi8+CjxyZWN0IHg9IjQiIHk9IjQiIHdpZHRoPSIzIiBoZWlnaHQ9IjEiIGZpbGw9IiMwNjA3MEEiLz4KPHJlY3QgeD0iNCIgeT0iNiIgd2lkdGg9IjUiIGhlaWdodD0iMSIgZmlsbD0iIzA2MDcwQSIvPgo8L2c+CjwvZz4KPGRlZnM+CjxsaW5lYXJHcmFkaWVudCBpZD0icGFpbnQwX2xpbmVhcl8xXzIxOCIgeDE9IjExIiB5MT0iNCIgeDI9IjExIiB5Mj0iMTUiIGdyYWRpZW50VW5pdHM9InVzZXJTcGFjZU9uVXNlIj4KPHN0b3Agc3RvcC1jb2xvcj0iIzdCODE4RCIvPgo8c3RvcCBvZmZzZXQ9IjEiIHN0b3AtY29sb3I9IiM0ODRBNTgiLz4KPC9saW5lYXJHcmFkaWVudD4KPGxpbmVhckdyYWRpZW50IGlkPSJwYWludDFfbGluZWFyXzFfMjE4IiB4MT0iNiIgeTE9IjEiIHgyPSI2IiB5Mj0iMTMiIGdyYWRpZW50VW5pdHM9InVzZXJTcGFjZU9uVXNlIj4KPHN0b3Agc3RvcC1jb2xvcj0iI0NDRDFGOSIvPgo8c3RvcCBvZmZzZXQ9IjEiIHN0b3AtY29sb3I9IiNCMkI0QkUiLz4KPC9saW5lYXJHcmFkaWVudD4KPGxpbmVhckdyYWRpZW50IGlkPSJwYWludDJfbGluZWFyXzFfMjE4IiB4MT0iOCIgeTE9IjEwIiB4Mj0iOCIgeTI9IjEzIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSI+CjxzdG9wIHN0b3AtY29sb3I9IiM3QTgwOEMiLz4KPHN0b3Agb2Zmc2V0PSIxIiBzdG9wLWNvbG9yPSIjNEE0QzVBIi8+CjwvbGluZWFyR3JhZGllbnQ+CjxsaW5lYXJHcmFkaWVudCBpZD0icGFpbnQzX2xpbmVhcl8xXzIxOCIgeDE9IjYiIHkxPSIwIiB4Mj0iNiIgeTI9IjE0IiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSI+CjxzdG9wIHN0b3AtY29sb3I9IiM5ODlDQjciLz4KPHN0b3Agb2Zmc2V0PSIxIiBzdG9wLWNvbG9yPSIjNUM1QzVDIi8+CjwvbGluZWFyR3JhZGllbnQ+CjxjbGlwUGF0aCBpZD0iY2xpcDBfMV8yMTgiPgo8cmVjdCB3aWR0aD0iMTYiIGhlaWdodD0iMTYiIGZpbGw9IndoaXRlIi8+CjwvY2xpcFBhdGg+CjxjbGlwUGF0aCBpZD0iY2xpcDFfMV8yMTgiPgo8cmVjdCB3aWR0aD0iMTAiIGhlaWdodD0iMTMiIGZpbGw9IndoaXRlIiB0cmFuc2Zvcm09InRyYW5zbGF0ZSg2IDMpIi8+CjwvY2xpcFBhdGg+CjxjbGlwUGF0aCBpZD0iY2xpcDJfMV8yMTgiPgo8cmVjdCB3aWR0aD0iMTIiIGhlaWdodD0iMTQiIGZpbGw9IndoaXRlIiB0cmFuc2Zvcm09InRyYW5zbGF0ZSgxIDEpIi8+CjwvY2xpcFBhdGg+CjxjbGlwUGF0aCBpZD0iY2xpcDNfMV8yMTgiPgo8cmVjdCB3aWR0aD0iMTIiIGhlaWdodD0iMTQiIGZpbGw9IndoaXRlIi8+CjwvY2xpcFBhdGg+CjwvZGVmcz4KPC9zdmc+Cg==); }
+button.action-button[hidden] { display: none; }
diff --git a/yomichan-user/conf.d/word-export.css.m4 b/yomichan-user/conf.d/word-export.css.m4
new file mode 100644
index 0000000..b4bd026
--- /dev/null
+++ b/yomichan-user/conf.d/word-export.css.m4
@@ -0,0 +1,2 @@
+.icon[data-icon=copy-bmp] { --icon-image: url`(data:image/svg+xml;base64,'undivert(copy-bitmap.svg.b64)`)'; }
+button.action-button[hidden] { display: none; }
diff --git a/yomichan-user/conf.d/word-export.js b/yomichan-user/conf.d/word-export.js
new file mode 100644
index 0000000..fce1b48
--- /dev/null
+++ b/yomichan-user/conf.d/word-export.js
@@ -0,0 +1,68 @@
+function exportWord() {
+ var entry = this.parentNode.parentNode.parentNode;
+ var wordElement = entry.getElementsByClassName("headword-term")[0];
+ var hasKanji = false;
+
+ function addWord(reading) {
+ var out = "";
+ for (var child of wordElement.childNodes) {
+ if (child.nodeName == "#text") out += child.textContent;
+ if (child.nodeName == "RUBY") {
+ hasKanji = true;
+ if (reading && out.length != 0) out += "\u30fb";
+ out += rubyHelper(child, reading);
+ }
+ }
+ return out;
+ }
+ var kanji = addWord(false);
+ var reading = addWord(true)
+ var result = `${kanji}`
+ if (hasKanji) result += `\u3010${reading}\u3011`;
+ else result += " ";
+
+ var tags = [];
+
+ var pitchAccent = "";
+ for (var tag of entry.getElementsByClassName("pronunciation-downstep-notation-number")) {
+ pitchAccent = tag.innerText.trim()
+ break;
+ }
+ if (pitchAccent) tags.push(`[${pitchAccent}]`);
+
+ var usuallyKana = false;
+ for (var tag of entry.getElementsByClassName("tag-label-content"))
+ if (tag.innerText.trim() == "uk")
+ usuallyKana = true;
+ if (usuallyKana) tags.push("(uk)");
+
+ result += tags.join(" ");
+
+ escapeYomichanCopy(result);
+}
+
+function addWordCopyButtons() {
+ var definitions = document.getElementById("dictionary-entries").getElementsByClassName("entry");
+ for (var definition of definitions) {
+ var actions = definition.getElementsByClassName("actions")[0];
+
+ var button = document.createElement("button");
+ button.classList.add("action-button");
+ button.onclick = exportWord;
+ var icon = document.createElement("span");
+ icon.classList.add("icon");
+ icon.classList.add("color-icon");
+ icon.classList.add("action-icon");
+ icon.setAttribute("data-icon", "copy-bmp");
+ button.appendChild(icon);
+ actions.insertBefore(button, actions.childNodes[0]);
+ }
+}
+
+(() => {
+ window.addEventListener("message", ev => {
+ // gets fired on search results render complete
+ if (ev.data.action == "renderMulti.response")
+ addWordCopyButtons();
+ });
+})();
diff --git a/yomichan-user/copy-bitmap.svg b/yomichan-user/copy-bitmap.svg
new file mode 100644
index 0000000..f2b157b
--- /dev/null
+++ b/yomichan-user/copy-bitmap.svg
@@ -0,0 +1,50 @@
+<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
+<g clip-path="url(#clip0_1_218)">
+<g clip-path="url(#clip1_1_218)">
+<path fill-rule="evenodd" clip-rule="evenodd" d="M12 4H7V7V15H12H15V7H12V4ZM13 5H14V6H13V5Z" fill="url(#paint0_linear_1_218)"/>
+<path fill-rule="evenodd" clip-rule="evenodd" d="M7 3H12H13V4H14V5H15V6H16V7V15V16H15L7 16H6V15V4V3H7ZM7 15V4H12V6V7H13H15V15H7ZM14 5H13L13 6H14V5Z" fill="black"/>
+</g>
+<g opacity="0.5" clip-path="url(#clip2_1_218)">
+<path d="M3 1V11H2V13H1V15H9V14H11V13H12V12H13V5H12V4H11V3H10V2H9V1H3Z" fill="black"/>
+</g>
+<g clip-path="url(#clip3_1_218)">
+<path fill-rule="evenodd" clip-rule="evenodd" d="M7 1H3V5H2V11H1V13H3H4H7V11H11V5H7V1ZM9 2H8V3V4H9H10V3H9V2Z" fill="url(#paint1_linear_1_218)"/>
+<path d="M10 10H6V13H10V10Z" fill="url(#paint2_linear_1_218)"/>
+<path fill-rule="evenodd" clip-rule="evenodd" d="M7 0H3H2V1V10H3V1H7V4V5H8H11V10H10V12H11V11H12V5V4H11V3H10V4H8L8 2H9V1H8V0H7ZM9 2H10V3H9V2ZM8 13V12H10V13H8ZM8 13V14H4V13H8ZM1 12H2V10H1V12ZM1 12H0V14H1V12Z" fill="url(#paint3_linear_1_218)"/>
+<path fill-rule="evenodd" clip-rule="evenodd" d="M7 9H8V10H7V11V12H6V13H5V14H1V13H4V12H5V11H6V10V9H7ZM8 10H10V11H8V10Z" fill="#06070A"/>
+<rect x="4" y="2" width="3" height="1" fill="#06070A"/>
+<rect x="4" y="4" width="3" height="1" fill="#06070A"/>
+<rect x="4" y="6" width="5" height="1" fill="#06070A"/>
+</g>
+</g>
+<defs>
+<linearGradient id="paint0_linear_1_218" x1="11" y1="4" x2="11" y2="15" gradientUnits="userSpaceOnUse">
+<stop stop-color="#7B818D"/>
+<stop offset="1" stop-color="#484A58"/>
+</linearGradient>
+<linearGradient id="paint1_linear_1_218" x1="6" y1="1" x2="6" y2="13" gradientUnits="userSpaceOnUse">
+<stop stop-color="#CCD1F9"/>
+<stop offset="1" stop-color="#B2B4BE"/>
+</linearGradient>
+<linearGradient id="paint2_linear_1_218" x1="8" y1="10" x2="8" y2="13" gradientUnits="userSpaceOnUse">
+<stop stop-color="#7A808C"/>
+<stop offset="1" stop-color="#4A4C5A"/>
+</linearGradient>
+<linearGradient id="paint3_linear_1_218" x1="6" y1="0" x2="6" y2="14" gradientUnits="userSpaceOnUse">
+<stop stop-color="#989CB7"/>
+<stop offset="1" stop-color="#5C5C5C"/>
+</linearGradient>
+<clipPath id="clip0_1_218">
+<rect width="16" height="16" fill="white"/>
+</clipPath>
+<clipPath id="clip1_1_218">
+<rect width="10" height="13" fill="white" transform="translate(6 3)"/>
+</clipPath>
+<clipPath id="clip2_1_218">
+<rect width="12" height="14" fill="white" transform="translate(1 1)"/>
+</clipPath>
+<clipPath id="clip3_1_218">
+<rect width="12" height="14" fill="white"/>
+</clipPath>
+</defs>
+</svg>
diff --git a/yomichan-user/makefile b/yomichan-user/makefile
index b965974..4e93d1a 100644
--- a/yomichan-user/makefile
+++ b/yomichan-user/makefile
@@ -2,18 +2,23 @@
all: yomichan-user.js yomichan-user.css
+user.js: conf.d/lib.js
user.js: conf.d/sentence-export.js
user.css: conf.d/sentence-export.css
-
user.css: conf.d/custom.css
+user.js: conf.d/word-export.js
+user.css: conf.d/word-export.css
include ../common.mk
copy.svg.b64: copy.svg
+copy-bitmap.svg.b64: copy-bitmap.svg
conf.d/sentence-export.css: copy.svg.b64
conf.d/sentence-export.css: conf.d/sentence-export.css.m4
+conf.d/word-export.css: copy-bitmap.svg.b64
+
user.js:
cat $^ > $@