diff options
| -rw-r--r-- | ext/bg/js/backend.js | 23 | ||||
| -rw-r--r-- | ext/bg/js/database.js | 2 | ||||
| -rw-r--r-- | ext/bg/js/dictionary-importer.js | 2 | ||||
| -rw-r--r-- | ext/bg/js/settings/dictionaries.js | 18 | ||||
| -rw-r--r-- | ext/bg/js/translator.js | 8 | ||||
| -rw-r--r-- | ext/bg/js/util.js | 25 | ||||
| -rw-r--r-- | ext/mixed/js/api.js | 10 | ||||
| -rw-r--r-- | test/test-database.js | 18 | 
8 files changed, 54 insertions, 52 deletions
| diff --git a/ext/bg/js/backend.js b/ext/bg/js/backend.js index c5173a2e..d454aa22 100644 --- a/ext/bg/js/backend.js +++ b/ext/bg/js/backend.js @@ -117,7 +117,10 @@ class Backend {              ['logIndicatorClear', {handler: this._onApiLogIndicatorClear.bind(this), async: false}],              ['createActionPort', {handler: this._onApiCreateActionPort.bind(this), async: false}]          ]); -        this._messageHandlersWithProgress = new Map(); +        this._messageHandlersWithProgress = new Map([ +            ['importDictionaryArchive', {handler: this._onApiImportDictionaryArchive.bind(this), async: true}], +            ['deleteDictionary', {handler: this._onApiDeleteDictionary.bind(this), async: true}] +        ]);          this._commandHandlers = new Map([              ['search', this._onCommandSearch.bind(this)], @@ -771,7 +774,8 @@ class Backend {      async _onApiPurgeDatabase(params, sender) {          this._validatePrivilegedMessageSender(sender); -        return await this.translator.purgeDatabase(); +        this.translator.clearDatabaseCaches(); +        await this.database.purge();      }      async _onApiGetMedia({targets}) { @@ -814,12 +818,23 @@ class Backend {          return portName;      } +    async _onApiImportDictionaryArchive({archiveContent, details}, sender, onProgress) { +        this._validatePrivilegedMessageSender(sender); +        return await this.dictionaryImporter.import(this.database, archiveContent, details, onProgress); +    } + +    async _onApiDeleteDictionary({dictionaryName}, sender, onProgress) { +        this._validatePrivilegedMessageSender(sender); +        this.translator.clearDatabaseCaches(); +        await this.database.deleteDictionary(dictionaryName, {rate: 1000}, onProgress); +    } +      // Command handlers      _createActionListenerPort(port, sender, handlers) {          let hasStarted = false; -        const onProgress = (data) => { +        const onProgress = (...data) => {              try {                  if (port === null) { return; }                  port.postMessage({type: 'progress', data}); @@ -847,7 +862,7 @@ class Backend {                  port.postMessage({type: 'complete', data: result});              } catch (e) {                  if (port !== null) { -                    port.postMessage({type: 'error', data: e}); +                    port.postMessage({type: 'error', data: errorToJson(e)});                  }                  cleanup();              } diff --git a/ext/bg/js/database.js b/ext/bg/js/database.js index a94aa720..930cd0d0 100644 --- a/ext/bg/js/database.js +++ b/ext/bg/js/database.js @@ -129,7 +129,7 @@ class Database {          await this.prepare();      } -    async deleteDictionary(dictionaryName, onProgress, progressSettings) { +    async deleteDictionary(dictionaryName, progressSettings, onProgress) {          this._validate();          const targets = [ diff --git a/ext/bg/js/dictionary-importer.js b/ext/bg/js/dictionary-importer.js index 3727f7ee..10e30cec 100644 --- a/ext/bg/js/dictionary-importer.js +++ b/ext/bg/js/dictionary-importer.js @@ -27,7 +27,7 @@ class DictionaryImporter {          this._schemas = new Map();      } -    async import(database, archiveSource, onProgress, details) { +    async import(database, archiveSource, details, onProgress) {          if (!database) {              throw new Error('Invalid database');          } diff --git a/ext/bg/js/settings/dictionaries.js b/ext/bg/js/settings/dictionaries.js index 50add4c7..632c01ea 100644 --- a/ext/bg/js/settings/dictionaries.js +++ b/ext/bg/js/settings/dictionaries.js @@ -17,8 +17,10 @@  /* global   * PageExitPrevention + * apiDeleteDictionary   * apiGetDictionaryCounts   * apiGetDictionaryInfo + * apiImportDictionaryArchive   * apiOptionsGet   * apiOptionsGetFull   * apiPurgeDatabase @@ -29,8 +31,6 @@   * storageEstimate   * storageUpdateStats   * utilBackgroundIsolate - * utilDatabaseDeleteDictionary - * utilDatabaseImport   */  let dictionaryUI = null; @@ -312,7 +312,7 @@ class SettingsDictionaryEntryUI {                  progressBar.style.width = `${percent}%`;              }; -            await utilDatabaseDeleteDictionary(this.dictionaryInfo.title, onProgress, {rate: 1000}); +            await apiDeleteDictionary(this.dictionaryInfo.title, onProgress);          } catch (e) {              dictionaryErrorsShow([e]);          } finally { @@ -679,7 +679,8 @@ async function onDictionaryImport(e) {                  dictImportInfo.textContent = `(${i + 1} of ${ii})`;              } -            const {result, errors} = await utilDatabaseImport(files[i], updateProgress, importDetails); +            const archiveContent = await dictReadFile(files[i]); +            const {result, errors} = await apiImportDictionaryArchive(archiveContent, importDetails, updateProgress);              for (const {options} of toIterable((await getOptionsFullMutable()).profiles)) {                  const dictionaryOptions = SettingsDictionaryListUI.createDictionaryOptions();                  dictionaryOptions.enabled = true; @@ -713,6 +714,15 @@ async function onDictionaryImport(e) {      }  } +function dictReadFile(file) { +    return new Promise((resolve, reject) => { +        const reader = new FileReader(); +        reader.onload = () => resolve(reader.result); +        reader.onerror = () => reject(reader.error); +        reader.readAsBinaryString(file); +    }); +} +  async function onDatabaseEnablePrefixWildcardSearchesChanged(e) {      const optionsFull = await getOptionsFullMutable(); diff --git a/ext/bg/js/translator.js b/ext/bg/js/translator.js index 8708e4d8..3fd329d1 100644 --- a/ext/bg/js/translator.js +++ b/ext/bg/js/translator.js @@ -45,14 +45,8 @@ class Translator {          this.deinflector = new Deinflector(reasons);      } -    async purgeDatabase() { +    clearDatabaseCaches() {          this.tagCache.clear(); -        await this.database.purge(); -    } - -    async deleteDictionary(dictionaryName) { -        this.tagCache.clear(); -        await this.database.deleteDictionary(dictionaryName);      }      async getSequencedDefinitions(definitions, mainDictionary) { diff --git a/ext/bg/js/util.js b/ext/bg/js/util.js index d2fb0e49..8f86e47a 100644 --- a/ext/bg/js/util.js +++ b/ext/bg/js/util.js @@ -66,31 +66,6 @@ function utilBackend() {      return backend;  } -async function utilDatabaseDeleteDictionary(dictionaryName, onProgress) { -    return utilIsolate(await utilBackend().translator.database.deleteDictionary( -        utilBackgroundIsolate(dictionaryName), -        utilBackgroundFunctionIsolate(onProgress) -    )); -} - -async function utilDatabaseImport(data, onProgress, details) { -    data = await utilReadFile(data); -    return utilIsolate(await utilBackend().importDictionary( -        utilBackgroundIsolate(data), -        utilBackgroundFunctionIsolate(onProgress), -        utilBackgroundIsolate(details) -    )); -} - -function utilReadFile(file) { -    return new Promise((resolve, reject) => { -        const reader = new FileReader(); -        reader.onload = () => resolve(reader.result); -        reader.onerror = () => reject(reader.error); -        reader.readAsBinaryString(file); -    }); -} -  function utilReadFileArrayBuffer(file) {      return new Promise((resolve, reject) => {          const reader = new FileReader(); diff --git a/ext/mixed/js/api.js b/ext/mixed/js/api.js index ca4bdd6c..af97ac3d 100644 --- a/ext/mixed/js/api.js +++ b/ext/mixed/js/api.js @@ -152,6 +152,14 @@ function apiLogIndicatorClear() {      return _apiInvoke('logIndicatorClear');  } +function apiImportDictionaryArchive(archiveContent, details, onProgress) { +    return _apiInvokeWithProgress('importDictionaryArchive', {archiveContent, details}, onProgress); +} + +function apiDeleteDictionary(dictionaryName, onProgress) { +    return _apiInvokeWithProgress('deleteDictionary', {dictionaryName}, onProgress); +} +  function _apiCreateActionPort(timeout=5000) {      return new Promise((resolve, reject) => {          let timer = null; @@ -213,7 +221,7 @@ function _apiInvokeWithProgress(action, params, onProgress, timeout=5000) {                      break;                  case 'progress':                      try { -                        onProgress(message.data); +                        onProgress(...message.data);                      } catch (e) {                          // NOP                      } diff --git a/test/test-database.js b/test/test-database.js index 3684051b..e8a4a343 100644 --- a/test/test-database.js +++ b/test/test-database.js @@ -233,10 +233,10 @@ async function testDatabase1() {                  let progressEvent = false;                  await database.deleteDictionary(                      title, +                    {rate: 1000},                      () => {                          progressEvent = true; -                    }, -                    {rate: 1000} +                    }                  );                  assert.ok(progressEvent); @@ -267,10 +267,10 @@ async function testDatabase1() {          const {result, errors} = await dictionaryImporter.import(              database,              testDictionarySource, +            {prefixWildcardsSupported: true},              () => {                  progressEvent = true; -            }, -            {prefixWildcardsSupported: true} +            }          );          vm.assert.deepStrictEqual(errors, []);          vm.assert.deepStrictEqual(result, expectedSummary); @@ -908,7 +908,7 @@ async function testDatabase2() {      // Error: not prepared      await assert.rejects(async () => await database.purge()); -    await assert.rejects(async () => await database.deleteDictionary(title, () => {}, {})); +    await assert.rejects(async () => await database.deleteDictionary(title, {}, () => {}));      await assert.rejects(async () => await database.findTermsBulk(['?'], titles, null));      await assert.rejects(async () => await database.findTermsExactBulk(['?'], ['?'], titles));      await assert.rejects(async () => await database.findTermsBySequenceBulk([1], title)); @@ -919,17 +919,17 @@ async function testDatabase2() {      await assert.rejects(async () => await database.findTagForTitle('tag', title));      await assert.rejects(async () => await database.getDictionaryInfo());      await assert.rejects(async () => await database.getDictionaryCounts(titles, true)); -    await assert.rejects(async () => await dictionaryImporter.import(database, testDictionarySource, () => {}, {})); +    await assert.rejects(async () => await dictionaryImporter.import(database, testDictionarySource, {}, () => {}));      await database.prepare();      // Error: already prepared      await assert.rejects(async () => await database.prepare()); -    await dictionaryImporter.import(database, testDictionarySource, () => {}, {}); +    await dictionaryImporter.import(database, testDictionarySource, {}, () => {});      // Error: dictionary already imported -    await assert.rejects(async () => await dictionaryImporter.import(database, testDictionarySource, () => {}, {})); +    await assert.rejects(async () => await dictionaryImporter.import(database, testDictionarySource, {}, () => {}));      await database.close();  } @@ -956,7 +956,7 @@ async function testDatabase3() {          let error = null;          try { -            await dictionaryImporter.import(database, testDictionarySource, () => {}, {}); +            await dictionaryImporter.import(database, testDictionarySource, {}, () => {});          } catch (e) {              error = e;          } |