diff options
| author | Loek Le Blansch <loek@pipeframe.xyz> | 2024-07-03 14:08:21 +0200 | 
|---|---|---|
| committer | Loek Le Blansch <loek@pipeframe.xyz> | 2024-07-03 14:08:21 +0200 | 
| commit | 0b905b2dd3d470301cef8bc22dfb2a323de826bb (patch) | |
| tree | cdebe8d10f156e98dff64866970adbe421e48dbf /ext/js | |
| parent | 066ca66fc4033da39d0aecd73b0f5c200cb3f3ed (diff) | |
Diffstat (limited to 'ext/js')
| -rw-r--r-- | ext/js/display/search-display-controller.js | 35 | ||||
| -rw-r--r-- | ext/js/refold-tools.js | 46 | 
2 files changed, 81 insertions, 0 deletions
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; +} +  |