diff options
| -rw-r--r-- | ext/bg/js/api.js | 113 | ||||
| -rw-r--r-- | ext/bg/js/backend.js | 143 | ||||
| -rw-r--r-- | ext/bg/js/settings.js | 18 | 
3 files changed, 144 insertions, 130 deletions
| diff --git a/ext/bg/js/api.js b/ext/bg/js/api.js index 36e283b9..9dbb69c1 100644 --- a/ext/bg/js/api.js +++ b/ext/bg/js/api.js @@ -17,72 +17,34 @@   */ -async function apiCommandExec(command) { -    const handlers = { -        search: () => { -            chrome.tabs.create({url: chrome.extension.getURL('/bg/search.html')}); -        }, - -        help: () => { -            chrome.tabs.create({url: 'https://foosoft.net/projects/yomichan/'}); -        }, +/* + * Backend + */ -        options: () => { -            chrome.runtime.openOptionsPage(); -        }, +function backend() { +    return chrome.extension.getBackgroundPage().yomichan_backend; +} -        toggle: () => { -            const options = chrome.extension.getBackgroundPage().yomichan.options; -            options.general.enable = !options.general.enable; -            optionsSave(options).then(() => apiOptionsSet(options)); -        } -    }; -    const handler = handlers[command]; -    if (handler) { -        handler(); -    } -} +/* + * API + */  async function apiOptionsSet(options) {      // In Firefox, setting options from the options UI somehow carries references      // to the DOM across to the background page, causing the options object to      // become a "DeadObject" after the options page is closed. The workaround used      // here is to create a deep copy of the options object. -    const yomichan = chrome.extension.getBackgroundPage().yomichan; -    yomichan.options = JSON.parse(JSON.stringify(options)); - -    if (!options.general.enable) { -        chrome.browserAction.setBadgeBackgroundColor({color: '#d9534f'}); -        chrome.browserAction.setBadgeText({text: 'off'}); -    } else if (!dictConfigured(options)) { -        chrome.browserAction.setBadgeBackgroundColor({color: '#f0ad4e'}); -        chrome.browserAction.setBadgeText({text: '!'}); -    } else { -        chrome.browserAction.setBadgeText({text: ''}); -    } - -    if (options.anki.enable) { -        yomichan.anki = new AnkiConnect(options.anki.server); -    } else { -        yomichan.anki = new AnkiNull(); -    } - -    chrome.tabs.query({}, tabs => { -        for (const tab of tabs) { -            chrome.tabs.sendMessage(tab.id, {action: 'optionsSet', params: options}, () => null); -        } -    }); +    backend().optionsSet(JSON.parse(JSON.stringify(options)));  }  async function apiOptionsGet() { -    return chrome.extension.getBackgroundPage().yomichan.options; +    return backend().options;  }  async function apiTermsFind(text) { -    const yomichan = chrome.extension.getBackgroundPage().yomichan; -    const options = yomichan.options; -    const translator = yomichan.translator; +    const options = backend().options; +    const translator = backend().translator;      const searcher = options.general.groupResults ?          translator.findTermsGrouped.bind(translator) : @@ -101,15 +63,13 @@ async function apiTermsFind(text) {  }  async function apiKanjiFind(text) { -    const yomichan = chrome.extension.getBackgroundPage().yomichan; -    const options = yomichan.options; -    const definitions = await yomichan.translator.findKanji(text, dictEnabledSet(options)); +    const options = backend().options; +    const definitions = await backend().translator.findKanji(text, dictEnabledSet(options));      return definitions.slice(0, options.general.maxResults);  }  async function apiDefinitionAdd(definition, mode) { -    const yomichan = chrome.extension.getBackgroundPage().yomichan; -    const options = yomichan.options; +    const options = backend().options;      if (mode !== 'kanji') {          await audioInject( @@ -119,21 +79,18 @@ async function apiDefinitionAdd(definition, mode) {          );      } -    return yomichan.anki.addNote(dictNoteFormat(definition, mode, options)); +    return backend().anki.addNote(dictNoteFormat(definition, mode, options));  }  async function apiDefinitionsAddable(definitions, modes) { -    const yomichan = chrome.extension.getBackgroundPage().yomichan; -    const options = yomichan.options; -      const notes = [];      for (const definition of definitions) {          for (const mode of modes) { -            notes.push(dictNoteFormat(definition, mode, options)); +            notes.push(dictNoteFormat(definition, mode, backend().options));          }      } -    const results = await yomichan.anki.canAddNotes(notes); +    const results = await backend().anki.canAddNotes(notes);      const states = [];      for (let resultBase = 0; resultBase < results.length; resultBase += modes.length) {          const state = {}; @@ -148,10 +105,38 @@ async function apiDefinitionsAddable(definitions, modes) {  }  async function apiNoteView(noteId) { -    const yomichan = chrome.extension.getBackgroundPage().yomichan; -    return yomichan.anki.guiBrowse(`nid:${noteId}`); +    return backend().anki.guiBrowse(`nid:${noteId}`);  }  async function apiTemplateRender(template, data) {      return handlebarsRender(template, data);  } + +async function apiCommandExec(command) { +    const handlers = { +        search: () => { +            chrome.tabs.create({url: chrome.extension.getURL('/bg/search.html')}); +        }, + +        help: () => { +            chrome.tabs.create({url: 'https://foosoft.net/projects/yomichan/'}); +        }, + +        options: () => { +            chrome.runtime.openOptionsPage(); +        }, + +        toggle: async () => { +            const options = backend().options; +            options.general.enable = !options.general.enable; +            await optionsSave(options); +            await apiOptionsSet(options); +        } +    }; + +    const handler = handlers[command]; +    if (handler) { +        handler(); +    } +} + diff --git a/ext/bg/js/backend.js b/ext/bg/js/backend.js index 2f60b4b7..6b345e6d 100644 --- a/ext/bg/js/backend.js +++ b/ext/bg/js/backend.js @@ -17,67 +17,102 @@   */ -window.yomichan = new class { +window.yomichan_backend = new class {      constructor() {          this.translator = new Translator();          this.anki = new AnkiNull();          this.options = null; +    } -        this.translator.prepare().then(optionsLoad).then(options => { -            apiOptionsSet(options); - -            chrome.commands.onCommand.addListener(apiCommandExec); -            chrome.runtime.onMessage.addListener(({action, params}, sender, callback) => { -                const forward = (promise, callback) => { -                    return promise.then(result => { -                        callback({result}); -                    }).catch(error => { -                        callback({error}); -                    }); -                }; - -                const handlers = { -                    optionsGet: ({callback}) => { -                        forward(optionsLoad(), callback); -                    }, - -                    kanjiFind: ({text, callback}) => { -                        forward(apiKanjiFind(text), callback); -                    }, - -                    termsFind: ({text, callback}) => { -                        forward(apiTermsFind(text), callback); -                    }, - -                    templateRender: ({template, data, callback}) => { -                        forward(apiTemplateRender(template, data), callback); -                    }, - -                    definitionAdd: ({definition, mode, callback}) => { -                        forward(apiDefinitionAdd(definition, mode), callback); -                    }, - -                    definitionsAddable: ({definitions, modes, callback}) => { -                        forward(apiDefinitionsAddable(definitions, modes), callback); -                    }, - -                    noteView: ({noteId}) => { -                        forward(apiNoteView(noteId), callback); -                    } -                }; - -                const handler = handlers[action]; -                if (handler) { -                    params.callback = callback; -                    handler(params); -                } - -                return true; -            }); +    async prepare() { +        await this.translator.prepare(); +        await apiOptionsSet(await optionsLoad()); + +        chrome.commands.onCommand.addListener(this.onCommand.bind(this)); +        chrome.runtime.onMessage.addListener(this.onMessage.bind(this)); + +        if (this.options.general.showGuide) { +            chrome.tabs.create({url: chrome.extension.getURL('/bg/guide.html')}); +        } +    } + +    optionsSet(options) { +        this.options = options; -            if (options.general.showGuide) { -                chrome.tabs.create({url: chrome.extension.getURL('/bg/guide.html')}); +        if (!options.general.enable) { +            chrome.browserAction.setBadgeBackgroundColor({color: '#d9534f'}); +            chrome.browserAction.setBadgeText({text: 'off'}); +        } else if (!dictConfigured(options)) { +            chrome.browserAction.setBadgeBackgroundColor({color: '#f0ad4e'}); +            chrome.browserAction.setBadgeText({text: '!'}); +        } else { +            chrome.browserAction.setBadgeText({text: ''}); +        } + +        if (options.anki.enable) { +            backend().anki = new AnkiConnect(options.anki.server); +        } else { +            backend().anki = new AnkiNull(); +        } + +        chrome.tabs.query({}, tabs => { +            for (const tab of tabs) { +                chrome.tabs.sendMessage(tab.id, {action: 'optionsSet', params: options}, () => null);              }          });      } + +    onCommand(command) { +        apiCommandExec(command); +    } + +    onMessage({action, params}, sender, callback) { +        const forward = (promise, callback) => { +            return promise.then(result => { +                callback({result}); +            }).catch(error => { +                callback({error}); +            }); +        }; + +        const handlers = { +            optionsGet: ({callback}) => { +                forward(optionsLoad(), callback); +            }, + +            kanjiFind: ({text, callback}) => { +                forward(apiKanjiFind(text), callback); +            }, + +            termsFind: ({text, callback}) => { +                forward(apiTermsFind(text), callback); +            }, + +            templateRender: ({template, data, callback}) => { +                forward(apiTemplateRender(template, data), callback); +            }, + +            definitionAdd: ({definition, mode, callback}) => { +                forward(apiDefinitionAdd(definition, mode), callback); +            }, + +            definitionsAddable: ({definitions, modes, callback}) => { +                forward(apiDefinitionsAddable(definitions, modes), callback); +            }, + +            noteView: ({noteId}) => { +                forward(apiNoteView(noteId), callback); +            } +        }; + +        const handler = handlers[action]; +        if (handler) { +            params.callback = callback; +            handler(params); +        } + +        return true; +    }  }; + +window.yomichan_backend.prepare(); diff --git a/ext/bg/js/settings.js b/ext/bg/js/settings.js index fa44c8da..1edbab01 100644 --- a/ext/bg/js/settings.js +++ b/ext/bg/js/settings.js @@ -22,33 +22,27 @@   */  function utilAnkiGetModelNames() { -    const yomichan = chrome.extension.getBackgroundPage().yomichan; -    return yomichan.anki.getModelNames(); +    return backend().anki.getModelNames();  }  function utilAnkiGetDeckNames() { -    const yomichan = chrome.extension.getBackgroundPage().yomichan; -    return yomichan.anki.getDeckNames(); +    return backend().anki.getDeckNames();  }  function utilAnkiGetModelFieldNames(modelName) { -    const yomichan = chrome.extension.getBackgroundPage().yomichan; -    return yomichan.anki.getModelFieldNames(modelName); +    return backend().anki.getModelFieldNames(modelName);  }  function utilDatabaseGetDictionaries() { -    const yomichan = chrome.extension.getBackgroundPage().yomichan; -    return yomichan.translator.database.getDictionaries(); +    return backend().translator.database.getDictionaries();  }  function utilDatabasePurge() { -    const yomichan = chrome.extension.getBackgroundPage().yomichan; -    return yomichan.translator.database.purge(); +    return backend().translator.database.purge();  }  function utilDatabaseImport(data, progress) { -    const yomichan = chrome.extension.getBackgroundPage().yomichan; -    return yomichan.translator.database.importDictionary(data, progress); +    return backend().translator.database.importDictionary(data, progress);  } |