diff options
Diffstat (limited to 'ext/bg/js')
| -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 +                } +            } +        } +    }  } |