diff options
Diffstat (limited to 'ext/bg')
-rw-r--r-- | ext/bg/js/anki-note-builder.js | 20 | ||||
-rw-r--r-- | ext/bg/js/backend.js | 55 |
2 files changed, 59 insertions, 16 deletions
diff --git a/ext/bg/js/anki-note-builder.js b/ext/bg/js/anki-note-builder.js index 4afb2d40..19e352f1 100644 --- a/ext/bg/js/anki-note-builder.js +++ b/ext/bg/js/anki-note-builder.js @@ -20,11 +20,12 @@ */ class AnkiNoteBuilder { - constructor({anki, audioSystem, renderTemplate, getClipboardImage=null}) { + constructor({anki, audioSystem, renderTemplate, getClipboardImage=null, getScreenshot=null}) { this._anki = anki; this._audioSystem = audioSystem; this._renderTemplate = renderTemplate; this._getClipboardImage = getClipboardImage; + this._getScreenshot = getScreenshot; } async createNote({ @@ -130,18 +131,23 @@ class AnkiNoteBuilder { async injectScreenshot(definition, fields, screenshot) { if (!this._containsMarker(fields, 'screenshot')) { return; } + const reading = definition.reading; const now = new Date(Date.now()); - let fileName = `yomichan_browser_screenshot_${definition.reading}_${this._dateToString(now)}.${screenshot.format}`; - fileName = AnkiNoteBuilder.replaceInvalidFileNameCharacters(fileName); - const data = screenshot.dataUrl.replace(/^data:[\w\W]*?,/, ''); try { + const {windowId, tabId, ownerFrameId, format, quality} = screenshot; + const dataUrl = await this._getScreenshot(windowId, tabId, ownerFrameId, format, quality); + + let fileName = `yomichan_browser_screenshot_${reading}_${this._dateToString(now)}.${format}`; + fileName = AnkiNoteBuilder.replaceInvalidFileNameCharacters(fileName); + const data = dataUrl.replace(/^data:[\w\W]*?,/, ''); + await this._anki.storeMediaFile(fileName, data); + + definition.screenshotFileName = fileName; } catch (e) { - return; + // NOP } - - definition.screenshotFileName = fileName; } async injectClipboardImage(definition, fields) { diff --git a/ext/bg/js/backend.js b/ext/bg/js/backend.js index 832dbc3a..47e68072 100644 --- a/ext/bg/js/backend.js +++ b/ext/bg/js/backend.js @@ -61,7 +61,8 @@ class Backend { anki: this._anki, audioSystem: this._audioSystem, renderTemplate: this._renderTemplate.bind(this), - getClipboardImage: this._onApiClipboardImageGet.bind(this) + getClipboardImage: this._onApiClipboardImageGet.bind(this), + getScreenshot: this._getScreenshot.bind(this) }); this._templateRenderer = new TemplateRenderer(); @@ -442,7 +443,7 @@ class Backend { return results; } - async _onApiDefinitionAdd({definition, mode, context, details, optionsContext}) { + async _onApiDefinitionAdd({definition, mode, context, ownerFrameId, optionsContext}, sender) { const options = this.getOptions(optionsContext); const templates = this._getTemplates(options); const fields = ( @@ -463,13 +464,13 @@ class Backend { await this._ankiNoteBuilder.injectClipboardImage(definition, fields); - if (details && details.screenshot) { - await this._ankiNoteBuilder.injectScreenshot( - definition, - fields, - details.screenshot - ); - } + const {id: tabId, windowId} = (sender && sender.tab ? sender.tab : {}); + const {format, quality} = options.anki.screenshot; + await this._ankiNoteBuilder.injectScreenshot( + definition, + fields, + {windowId, tabId, ownerFrameId, format, quality} + ); const note = await this._createNote(definition, mode, context, options, templates); return this._anki.addNote(note); @@ -1626,4 +1627,40 @@ class Backend { modeOptions }); } + + async _getScreenshot(windowId, tabId, ownerFrameId, format, quality) { + if (typeof windowId !== 'number') { + throw new Error('Invalid window ID'); + } + + let token = null; + try { + if (typeof tabId === 'number' && typeof ownerFrameId === 'number') { + const action = 'setAllVisibleOverride'; + const params = {value: false, priority: 0, awaitFrame: true}; + token = await this._sendMessageTab(tabId, {action, params}, {frameId: ownerFrameId}); + } + + return await new Promise((resolve, reject) => { + chrome.tabs.captureVisibleTab(windowId, {format, quality}, (result) => { + const e = chrome.runtime.lastError; + if (e) { + reject(new Error(e.message)); + } else { + resolve(result); + } + }); + }); + } finally { + if (token !== null) { + const action = 'clearAllVisibleOverride'; + const params = {token}; + try { + await this._sendMessageTab(tabId, {action, params}, {frameId: ownerFrameId}); + } catch (e) { + // NOP + } + } + } + } } |