diff options
author | toasted-nutbread <toasted-nutbread@users.noreply.github.com> | 2020-09-09 16:57:35 -0400 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-09-09 16:57:35 -0400 |
commit | acb7ad32f39c40b879400c9daa4bc8cd25585ba7 (patch) | |
tree | 4b40ca7ccf64d2d685aafa8e0d637ffff604e64a /ext/bg/js/anki-note-builder.js | |
parent | c0a6849f98d433e8dbcaa8c2cb0e995174399d3c (diff) |
Anki media injection move (#793)
* Update AnkiNoteBuilder to not store a reference to an AniConnect instance
* Use more consistent details format
* Organize options assignment
* Move media injection
* Inject images before injecting audio
* Make functions private
* Make static functions private
Diffstat (limited to 'ext/bg/js/anki-note-builder.js')
-rw-r--r-- | ext/bg/js/anki-note-builder.js | 64 |
1 files changed, 43 insertions, 21 deletions
diff --git a/ext/bg/js/anki-note-builder.js b/ext/bg/js/anki-note-builder.js index c5f87cb8..b46bf3ba 100644 --- a/ext/bg/js/anki-note-builder.js +++ b/ext/bg/js/anki-note-builder.js @@ -20,8 +20,7 @@ */ class AnkiNoteBuilder { - constructor({anki, audioSystem, renderTemplate, getClipboardImage=null, getScreenshot=null}) { - this._anki = anki; + constructor({audioSystem, renderTemplate, getClipboardImage=null, getScreenshot=null}) { this._audioSystem = audioSystem; this._renderTemplate = renderTemplate; this._getClipboardImage = getClipboardImage; @@ -29,6 +28,7 @@ class AnkiNoteBuilder { } async createNote({ + anki=null, definition, mode, context, @@ -38,8 +38,15 @@ class AnkiNoteBuilder { resultOutputMode='split', compactGlossaries=false, modeOptions: {fields, deck, model}, + audioDetails=null, + screenshotDetails=null, + clipboardImage=false, errors=null }) { + if (anki !== null) { + await this._injectMedia(anki, definition, fields, mode, audioDetails, screenshotDetails, clipboardImage); + } + const fieldEntries = Object.entries(fields); const noteFields = {}; const note = { @@ -50,10 +57,10 @@ class AnkiNoteBuilder { options: {duplicateScope} }; - const data = this.createNoteData(definition, mode, context, resultOutputMode, compactGlossaries); + const data = this._createNoteData(definition, mode, context, resultOutputMode, compactGlossaries); const formattedFieldValuePromises = []; for (const [, fieldValue] of fieldEntries) { - const formattedFieldValuePromise = this.formatField(fieldValue, data, templates, errors); + const formattedFieldValuePromise = this._formatField(fieldValue, data, templates, errors); formattedFieldValuePromises.push(formattedFieldValuePromise); } @@ -67,7 +74,9 @@ class AnkiNoteBuilder { return note; } - createNoteData(definition, mode, context, resultOutputMode, compactGlossaries) { + // Private + + _createNoteData(definition, mode, context, resultOutputMode, compactGlossaries) { const pitches = DictionaryDataUtil.getPitchAccentInfos(definition); const pitchCount = pitches.reduce((i, v) => i + v.pitches.length, 0); return { @@ -85,9 +94,9 @@ class AnkiNoteBuilder { }; } - async formatField(field, data, templates, errors=null) { + async _formatField(field, data, templates, errors=null) { const pattern = /\{([\w-]+)\}/g; - return await AnkiNoteBuilder.stringReplaceAsync(field, pattern, async (g0, marker) => { + return await this._stringReplaceAsync(field, pattern, async (g0, marker) => { try { return await this._renderTemplate(templates, data, marker); } catch (e) { @@ -97,16 +106,29 @@ class AnkiNoteBuilder { }); } - async injectAudio(definition, fields, sources, customSourceUrl) { + async _injectMedia(anki, definition, fields, mode, audioDetails, screenshotDetails, clipboardImage) { + if (screenshotDetails !== null) { + await this._injectScreenshot(anki, definition, fields, screenshotDetails); + } + if (clipboardImage) { + await this._injectClipboardImage(anki, definition, fields); + } + if (mode !== 'kanji' && audioDetails !== null) { + await this._injectAudio(anki, definition, fields, audioDetails); + } + } + + async _injectAudio(anki, definition, fields, details) { if (!this._containsMarker(fields, 'audio')) { return; } try { + const {sources, customSourceUrl} = details; const expressions = definition.expressions; const audioSourceDefinition = Array.isArray(expressions) ? expressions[0] : definition; let fileName = this._createInjectedAudioFileName(audioSourceDefinition); if (fileName === null) { return; } - fileName = AnkiNoteBuilder.replaceInvalidFileNameCharacters(fileName); + fileName = this._replaceInvalidFileNameCharacters(fileName); const {audio} = await this._audioSystem.getDefinitionAudio( audioSourceDefinition, @@ -119,8 +141,8 @@ class AnkiNoteBuilder { } ); - const data = AnkiNoteBuilder.arrayBufferToBase64(audio); - await this._anki.storeMediaFile(fileName, data); + const data = this._arrayBufferToBase64(audio); + await anki.storeMediaFile(fileName, data); definition.audioFileName = fileName; } catch (e) { @@ -128,14 +150,14 @@ class AnkiNoteBuilder { } } - async injectScreenshot(definition, fields, screenshot) { + async _injectScreenshot(anki, definition, fields, details) { if (!this._containsMarker(fields, 'screenshot')) { return; } const reading = definition.reading; const now = new Date(Date.now()); try { - const {windowId, tabId, ownerFrameId, format, quality} = screenshot; + const {windowId, tabId, ownerFrameId, format, quality} = details; const dataUrl = await this._getScreenshot(windowId, tabId, ownerFrameId, format, quality); const {mediaType, data} = this._getDataUrlInfo(dataUrl); @@ -143,9 +165,9 @@ class AnkiNoteBuilder { if (extension === null) { return; } let fileName = `yomichan_browser_screenshot_${reading}_${this._dateToString(now)}.${extension}`; - fileName = AnkiNoteBuilder.replaceInvalidFileNameCharacters(fileName); + fileName = this._replaceInvalidFileNameCharacters(fileName); - await this._anki.storeMediaFile(fileName, data); + await anki.storeMediaFile(fileName, data); definition.screenshotFileName = fileName; } catch (e) { @@ -153,7 +175,7 @@ class AnkiNoteBuilder { } } - async injectClipboardImage(definition, fields) { + async _injectClipboardImage(anki, definition, fields) { if (!this._containsMarker(fields, 'clipboard-image')) { return; } const reading = definition.reading; @@ -168,9 +190,9 @@ class AnkiNoteBuilder { if (extension === null) { return; } let fileName = `yomichan_clipboard_image_${reading}_${this._dateToString(now)}.${extension}`; - fileName = AnkiNoteBuilder.replaceInvalidFileNameCharacters(fileName); + fileName = this._replaceInvalidFileNameCharacters(fileName); - await this._anki.storeMediaFile(fileName, data); + await anki.storeMediaFile(fileName, data); definition.clipboardImageFileName = fileName; } catch (e) { @@ -233,16 +255,16 @@ class AnkiNoteBuilder { } } - static replaceInvalidFileNameCharacters(fileName) { + _replaceInvalidFileNameCharacters(fileName) { // eslint-disable-next-line no-control-regex return fileName.replace(/[<>:"/\\|?*\x00-\x1F]/g, '-'); } - static arrayBufferToBase64(arrayBuffer) { + _arrayBufferToBase64(arrayBuffer) { return btoa(String.fromCharCode(...new Uint8Array(arrayBuffer))); } - static stringReplaceAsync(str, regex, replacer) { + _stringReplaceAsync(str, regex, replacer) { let match; let index = 0; const parts = []; |