From 0b905b2dd3d470301cef8bc22dfb2a323de826bb Mon Sep 17 00:00:00 2001 From: Loek Le Blansch Date: Wed, 3 Jul 2024 14:08:21 +0200 Subject: WIP transfer refold-tools to yomitan fork --- ext/css/display.css | 2 +- ext/css/material.css | 2 + ext/images/copy-bitmap.svg | 58 +++++++++++++++++++++++++++++ ext/images/copy.svg | 3 ++ ext/js/display/search-display-controller.js | 35 +++++++++++++++++ ext/js/refold-tools.js | 46 +++++++++++++++++++++++ ext/search.html | 1 + ext/templates-display.html | 3 ++ makefile | 8 ++++ 9 files changed, 157 insertions(+), 1 deletion(-) create mode 100644 ext/images/copy-bitmap.svg create mode 100644 ext/images/copy.svg create mode 100644 ext/js/refold-tools.js create mode 100644 makefile diff --git a/ext/css/display.css b/ext/css/display.css index febcb62b..f04865a8 100644 --- a/ext/css/display.css +++ b/ext/css/display.css @@ -646,7 +646,7 @@ button.action-button { background-color var(--animation-duration) linear; } button.action-button[hidden] { - display: block; + display: none; visibility: hidden; opacity: 0; transition: diff --git a/ext/css/material.css b/ext/css/material.css index 00265586..d93b31d5 100644 --- a/ext/css/material.css +++ b/ext/css/material.css @@ -290,6 +290,8 @@ body { --icon-image: url(/images/material-right-arrow.svg); --icon-size: var(--material-arrow-dimension1) var(--material-arrow-dimension2); } +.icon[data-icon=copy] { --icon-image: url('/images/copy.svg'); } +.icon[data-icon=copy-bmp] { --icon-image: url('/images/copy-bitmap.svg'); } /* Checkbox */ diff --git a/ext/images/copy-bitmap.svg b/ext/images/copy-bitmap.svg new file mode 100644 index 00000000..79497640 --- /dev/null +++ b/ext/images/copy-bitmap.svg @@ -0,0 +1,58 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/ext/images/copy.svg b/ext/images/copy.svg new file mode 100644 index 00000000..ff2f5a9d --- /dev/null +++ b/ext/images/copy.svg @@ -0,0 +1,3 @@ + + + diff --git a/ext/js/display/search-display-controller.js b/ext/js/display/search-display-controller.js index b1e26750..20adbc82 100644 --- a/ext/js/display/search-display-controller.js +++ b/ext/js/display/search-display-controller.js @@ -21,6 +21,7 @@ import {ClipboardMonitor} from '../comm/clipboard-monitor.js'; import {createApiMap, invokeApiMapHandler} from '../core/api-map.js'; import {EventListenerCollection} from '../core/event-listener-collection.js'; import {querySelectorNotNull} from '../dom/query-selector.js'; +import { escapeYomichanCopy } from '../refold-tools.js'; export class SearchDisplayController { /** @@ -36,6 +37,8 @@ export class SearchDisplayController { /** @type {import('./search-persistent-state-controller.js').SearchPersistentStateController} */ this._searchPersistentStateController = searchPersistentStateController; /** @type {HTMLButtonElement} */ + this._copySentenceButton = querySelectorNotNull(document, '#anki-sentence-export-button'); + /** @type {HTMLButtonElement} */ this._searchButton = querySelectorNotNull(document, '#search-button'); /** @type {HTMLButtonElement} */ this._searchBackButton = querySelectorNotNull(document, '#search-back-button'); @@ -101,6 +104,7 @@ export class SearchDisplayController { this._display.queryParserVisible = true; this._display.setHistorySettings({useBrowserHistory: true}); + this._copySentenceButton.addEventListener('click', this._onCopySentence.bind(this), false); this._searchButton.addEventListener('click', this._onSearch.bind(this), false); this._searchBackButton.addEventListener('click', this._onSearchBackButtonClick.bind(this), false); this._wanakanaEnableCheckbox.addEventListener('change', this._onWanakanaEnableChange.bind(this)); @@ -255,6 +259,37 @@ export class SearchDisplayController { this._search(true, 'new', true, null); } + /** @param {MouseEvent} e */ + _onCopySentence(e) { + e.preventDefault(); + var inputHTML = document.getElementById("query-parser-content"); + var output = ""; + + var selection = window.getSelection(); + // TODO: fix right-to-left selected text + + for (var child of inputHTML.children) { + for (var subchild of child.childNodes) { + if (subchild.nodeName == '#text') { + for (var i in subchild.textContent) { + if (selection.anchorNode == subchild && i == selection.anchorOffset) output += "*"; + output += subchild.textContent[i]; + if (selection.focusNode == subchild && i == selection.focusOffset - 1) output += "*"; + } + continue; + } + if (subchild.nodeName == 'RUBY') { + if (selection.anchorNode.parentNode.parentNode == subchild) output += "*"; + output += `[${subchild.childNodes[0].innerText}](${subchild.childNodes[1].innerText})`; + if (selection.focusNode.parentNode.parentNode == subchild) output += "*"; + continue; + } + } + } + + escapeYomichanCopy(output); + } + /** * @param {MouseEvent} e */ diff --git a/ext/js/refold-tools.js b/ext/js/refold-tools.js new file mode 100644 index 00000000..99fc114f --- /dev/null +++ b/ext/js/refold-tools.js @@ -0,0 +1,46 @@ +// TODO: how to get yomichan.api? + +export async function getClipboardSettings() { + return (await yomichan.api.getSettings([{ + scope: "profile", + optionsContext: { current: true }, + path: 'clipboard' + }]))[0].result; +} + +export async function setClipboardSettings(settings) { + await yomichan.api.modifySettings([{ + scope: "profile", + optionsContext: { current: true }, + path: 'clipboard', + action: 'set', + value: settings + }]); +} + +export 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); +} + +export 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.textContent; + } + return out; +} + diff --git a/ext/search.html b/ext/search.html index 4324dad5..e2c2f525 100644 --- a/ext/search.html +++ b/ext/search.html @@ -59,6 +59,7 @@
+
diff --git a/ext/templates-display.html b/ext/templates-display.html index f52fb1fa..a96c7d50 100644 --- a/ext/templates-display.html +++ b/ext/templates-display.html @@ -5,6 +5,9 @@
+ diff --git a/makefile b/makefile new file mode 100644 index 00000000..4fce012f --- /dev/null +++ b/makefile @@ -0,0 +1,8 @@ +all: build FORCE + +build: FORCE + npm run-script build + + + +.PHONY: FORCE -- cgit v1.2.3