Add clipboard-text Anki field (#863)
* Add clipboard-text anki field * Add markers * Update clipboard injection
This commit is contained in:
parent
d27349207d
commit
cab5daa22e
@ -155,6 +155,7 @@ Flashcard fields can be configured with the following steps:
|
|||||||
-------|------------
|
-------|------------
|
||||||
`{audio}` | Audio sample of a native speaker's pronunciation in MP3 format (if available).
|
`{audio}` | Audio sample of a native speaker's pronunciation in MP3 format (if available).
|
||||||
`{clipboard-image}` | An image which is stored in the system clipboard, if present.
|
`{clipboard-image}` | An image which is stored in the system clipboard, if present.
|
||||||
|
`{clipboard-text}` | Text which is stored in the system clipboard, if present.
|
||||||
`{cloze-body}` | Raw, inflected term as it appeared before being reduced to dictionary form by Yomichan.
|
`{cloze-body}` | Raw, inflected term as it appeared before being reduced to dictionary form by Yomichan.
|
||||||
`{cloze-prefix}` | Fragment of the containing `{sentence}` starting at the beginning of `{sentence}` until the beginning of `{cloze-body}`.
|
`{cloze-prefix}` | Fragment of the containing `{sentence}` starting at the beginning of `{sentence}` until the beginning of `{cloze-body}`.
|
||||||
`{cloze-suffix}` | Fragment of the containing `{sentence}` starting at the end of `{cloze-body}` until the end of `{sentence}`.
|
`{cloze-suffix}` | Fragment of the containing `{sentence}` starting at the end of `{cloze-body}` until the end of `{sentence}`.
|
||||||
@ -180,6 +181,7 @@ Flashcard fields can be configured with the following steps:
|
|||||||
-------|------------
|
-------|------------
|
||||||
`{character}` | Unicode glyph representing the current kanji.
|
`{character}` | Unicode glyph representing the current kanji.
|
||||||
`{clipboard-image}` | An image which is stored in the system clipboard, if present.
|
`{clipboard-image}` | An image which is stored in the system clipboard, if present.
|
||||||
|
`{clipboard-text}` | Text which is stored in the system clipboard, if present.
|
||||||
`{cloze-body}` | Raw, inflected parent term as it appeared before being reduced to dictionary form by Yomichan.
|
`{cloze-body}` | Raw, inflected parent term as it appeared before being reduced to dictionary form by Yomichan.
|
||||||
`{cloze-prefix}` | Fragment of the containing `{sentence}` starting at the beginning of `{sentence}` until the beginning of `{cloze-body}`.
|
`{cloze-prefix}` | Fragment of the containing `{sentence}` starting at the beginning of `{sentence}` until the beginning of `{cloze-body}`.
|
||||||
`{cloze-suffix}` | Fragment of the containing `{sentence}` starting at the end of `{cloze-body}` until the end of `{sentence}`.
|
`{cloze-suffix}` | Fragment of the containing `{sentence}` starting at the end of `{cloze-body}` until the end of `{sentence}`.
|
||||||
|
@ -3,3 +3,7 @@
|
|||||||
<img src="{{definition.clipboardImageFileName}}" />
|
<img src="{{definition.clipboardImageFileName}}" />
|
||||||
{{~/if~}}
|
{{~/if~}}
|
||||||
{{/inline}}
|
{{/inline}}
|
||||||
|
|
||||||
|
{{#*inline "clipboard-text"}}
|
||||||
|
{{~#if definition.clipboardText~}}{{definition.clipboardText}}{{~/if~}}
|
||||||
|
{{/inline}}
|
||||||
|
@ -282,4 +282,8 @@
|
|||||||
{{~/if~}}
|
{{~/if~}}
|
||||||
{{/inline}}
|
{{/inline}}
|
||||||
|
|
||||||
|
{{#*inline "clipboard-text"}}
|
||||||
|
{{~#if definition.clipboardText~}}{{definition.clipboardText}}{{~/if~}}
|
||||||
|
{{/inline}}
|
||||||
|
|
||||||
{{~> (lookup . "marker") ~}}
|
{{~> (lookup . "marker") ~}}
|
||||||
|
@ -37,11 +37,11 @@ class AnkiNoteBuilder {
|
|||||||
modeOptions: {fields, deck, model},
|
modeOptions: {fields, deck, model},
|
||||||
audioDetails=null,
|
audioDetails=null,
|
||||||
screenshotDetails=null,
|
screenshotDetails=null,
|
||||||
clipboardImage=false,
|
clipboardDetails=null,
|
||||||
errors=null
|
errors=null
|
||||||
}) {
|
}) {
|
||||||
if (anki !== null) {
|
if (anki !== null) {
|
||||||
await this._injectMedia(anki, definition, fields, mode, audioDetails, screenshotDetails, clipboardImage);
|
await this._injectMedia(anki, definition, fields, mode, audioDetails, screenshotDetails, clipboardDetails);
|
||||||
}
|
}
|
||||||
|
|
||||||
const fieldEntries = Object.entries(fields);
|
const fieldEntries = Object.entries(fields);
|
||||||
|
@ -452,7 +452,7 @@ class Backend {
|
|||||||
return results;
|
return results;
|
||||||
}
|
}
|
||||||
|
|
||||||
async _onApiInjectAnkiNoteMedia({expression, reading, timestamp, audioDetails, screenshotDetails, clipboardImage}, sender) {
|
async _onApiInjectAnkiNoteMedia({expression, reading, timestamp, audioDetails, screenshotDetails, clipboardDetails}, sender) {
|
||||||
if (isObject(screenshotDetails)) {
|
if (isObject(screenshotDetails)) {
|
||||||
const {id: tabId, windowId} = (sender && sender.tab ? sender.tab : {});
|
const {id: tabId, windowId} = (sender && sender.tab ? sender.tab : {});
|
||||||
screenshotDetails = Object.assign({}, screenshotDetails, {tabId, windowId});
|
screenshotDetails = Object.assign({}, screenshotDetails, {tabId, windowId});
|
||||||
@ -464,7 +464,7 @@ class Backend {
|
|||||||
timestamp,
|
timestamp,
|
||||||
audioDetails,
|
audioDetails,
|
||||||
screenshotDetails,
|
screenshotDetails,
|
||||||
clipboardImage
|
clipboardDetails
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1512,23 +1512,31 @@ class Backend {
|
|||||||
return await this._audioDownloader.downloadAudio(sources, expression, reading, details);
|
return await this._audioDownloader.downloadAudio(sources, expression, reading, details);
|
||||||
}
|
}
|
||||||
|
|
||||||
async _injectAnkNoteMedia(ankiConnect, expression, reading, timestamp, audioDetails, screenshotDetails, clipboardImage) {
|
async _injectAnkNoteMedia(ankiConnect, expression, reading, timestamp, audioDetails, screenshotDetails, clipboardDetails) {
|
||||||
const screenshotFileName = (
|
const screenshotFileName = (
|
||||||
screenshotDetails !== null ?
|
screenshotDetails !== null ?
|
||||||
await this._injectAnkNoteScreenshot(ankiConnect, expression, reading, timestamp, screenshotDetails) :
|
await this._injectAnkNoteScreenshot(ankiConnect, expression, reading, timestamp, screenshotDetails) :
|
||||||
null
|
null
|
||||||
);
|
);
|
||||||
const clipboardImageFileName = (
|
const clipboardImageFileName = (
|
||||||
clipboardImage ?
|
clipboardDetails !== null && clipboardDetails.image ?
|
||||||
await this._injectAnkNoteClipboardImage(ankiConnect, expression, reading, timestamp) :
|
await this._injectAnkNoteClipboardImage(ankiConnect, expression, reading, timestamp) :
|
||||||
null
|
null
|
||||||
);
|
);
|
||||||
|
let clipboardText = null;
|
||||||
|
try {
|
||||||
|
if (clipboardDetails !== null && clipboardDetails.text) {
|
||||||
|
clipboardText = await this._clipboardReader.getText();
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
// NOP
|
||||||
|
}
|
||||||
const audioFileName = (
|
const audioFileName = (
|
||||||
audioDetails !== null ?
|
audioDetails !== null ?
|
||||||
await this._injectAnkNoteAudio(ankiConnect, expression, reading, timestamp, audioDetails) :
|
await this._injectAnkNoteAudio(ankiConnect, expression, reading, timestamp, audioDetails) :
|
||||||
null
|
null
|
||||||
);
|
);
|
||||||
return {screenshotFileName, clipboardImageFileName, audioFileName};
|
return {screenshotFileName, clipboardImageFileName, clipboardText, audioFileName};
|
||||||
}
|
}
|
||||||
|
|
||||||
async _injectAnkNoteAudio(ankiConnect, expression, reading, timestamp, details) {
|
async _injectAnkNoteAudio(ankiConnect, expression, reading, timestamp, details) {
|
||||||
|
@ -503,6 +503,7 @@ class OptionsUtil {
|
|||||||
// Options conditions converted to string representations.
|
// Options conditions converted to string representations.
|
||||||
// Added usePopupWindow.
|
// Added usePopupWindow.
|
||||||
// Updated handlebars templates to include "clipboard-image" definition.
|
// Updated handlebars templates to include "clipboard-image" definition.
|
||||||
|
// Updated handlebars templates to include "clipboard-text" definition.
|
||||||
// Added hideDelay.
|
// Added hideDelay.
|
||||||
// Added inputs to profileOptions.scanning.
|
// Added inputs to profileOptions.scanning.
|
||||||
// Added pointerEventsEnabled to profileOptions.scanning.
|
// Added pointerEventsEnabled to profileOptions.scanning.
|
||||||
|
@ -46,6 +46,7 @@ class AnkiController {
|
|||||||
return [
|
return [
|
||||||
'audio',
|
'audio',
|
||||||
'clipboard-image',
|
'clipboard-image',
|
||||||
|
'clipboard-text',
|
||||||
'cloze-body',
|
'cloze-body',
|
||||||
'cloze-prefix',
|
'cloze-prefix',
|
||||||
'cloze-suffix',
|
'cloze-suffix',
|
||||||
@ -69,6 +70,7 @@ class AnkiController {
|
|||||||
return [
|
return [
|
||||||
'character',
|
'character',
|
||||||
'clipboard-image',
|
'clipboard-image',
|
||||||
|
'clipboard-text',
|
||||||
'cloze-body',
|
'cloze-body',
|
||||||
'cloze-prefix',
|
'cloze-prefix',
|
||||||
'cloze-suffix',
|
'cloze-suffix',
|
||||||
|
@ -77,8 +77,8 @@ const api = (() => {
|
|||||||
return this._invoke('getAnkiNoteInfo', {notes, duplicateScope});
|
return this._invoke('getAnkiNoteInfo', {notes, duplicateScope});
|
||||||
}
|
}
|
||||||
|
|
||||||
injectAnkiNoteMedia(expression, reading, timestamp, audioDetails, screenshotDetails, clipboardImage) {
|
injectAnkiNoteMedia(expression, reading, timestamp, audioDetails, screenshotDetails, clipboardDetails) {
|
||||||
return this._invoke('injectAnkiNoteMedia', {expression, reading, timestamp, audioDetails, screenshotDetails, clipboardImage});
|
return this._invoke('injectAnkiNoteMedia', {expression, reading, timestamp, audioDetails, screenshotDetails, clipboardDetails});
|
||||||
}
|
}
|
||||||
|
|
||||||
noteView(noteId) {
|
noteView(noteId) {
|
||||||
|
@ -1389,18 +1389,22 @@ class Display extends EventDispatcher {
|
|||||||
const {expression, reading} = Array.isArray(definitionExpressions) ? definitionExpressions[0] : definition;
|
const {expression, reading} = Array.isArray(definitionExpressions) ? definitionExpressions[0] : definition;
|
||||||
const audioDetails = (mode !== 'kanji' && this._ankiNoteBuilder.containsMarker(fields, 'audio') ? {sources, customSourceUrl} : null);
|
const audioDetails = (mode !== 'kanji' && this._ankiNoteBuilder.containsMarker(fields, 'audio') ? {sources, customSourceUrl} : null);
|
||||||
const screenshotDetails = (this._ankiNoteBuilder.containsMarker(fields, 'screenshot') ? {ownerFrameId, format, quality} : null);
|
const screenshotDetails = (this._ankiNoteBuilder.containsMarker(fields, 'screenshot') ? {ownerFrameId, format, quality} : null);
|
||||||
const clipboardImage = (this._ankiNoteBuilder.containsMarker(fields, 'clipboard-image'));
|
const clipboardDetails = {
|
||||||
const {screenshotFileName, clipboardImageFileName, audioFileName} = await api.injectAnkiNoteMedia(
|
image: this._ankiNoteBuilder.containsMarker(fields, 'clipboard-image'),
|
||||||
|
text: this._ankiNoteBuilder.containsMarker(fields, 'clipboard-text')
|
||||||
|
};
|
||||||
|
const {screenshotFileName, clipboardImageFileName, clipboardText, audioFileName} = await api.injectAnkiNoteMedia(
|
||||||
expression,
|
expression,
|
||||||
reading,
|
reading,
|
||||||
timestamp,
|
timestamp,
|
||||||
audioDetails,
|
audioDetails,
|
||||||
screenshotDetails,
|
screenshotDetails,
|
||||||
clipboardImage
|
clipboardDetails
|
||||||
);
|
);
|
||||||
if (screenshotFileName !== null) { definition.screenshotFileName = screenshotFileName; }
|
if (screenshotFileName !== null) { definition.screenshotFileName = screenshotFileName; }
|
||||||
if (clipboardImageFileName !== null) { definition.clipboardImageFileName = clipboardImageFileName; }
|
if (clipboardImageFileName !== null) { definition.clipboardImageFileName = clipboardImageFileName; }
|
||||||
if (audioFileName !== null) { definition.audioFileName = audioFileName; }
|
if (audioFileName !== null) { definition.audioFileName = audioFileName; }
|
||||||
|
if (clipboardText !== null) { definition.clipboardText = clipboardText; }
|
||||||
}
|
}
|
||||||
|
|
||||||
return await this._ankiNoteBuilder.createNote({
|
return await this._ankiNoteBuilder.createNote({
|
||||||
|
Loading…
Reference in New Issue
Block a user