diff options
| author | toasted-nutbread <toasted-nutbread@users.noreply.github.com> | 2020-03-01 14:41:48 -0500 | 
|---|---|---|
| committer | GitHub <noreply@github.com> | 2020-03-01 14:41:48 -0500 | 
| commit | a4b0a556d48f2b0ae4208f69fa651d2370529db5 (patch) | |
| tree | 5a304f9be64829e07d311bbf51871aeda28fe10b | |
| parent | 7c615244f40222584984157223944e6aa6448d13 (diff) | |
| parent | 8e29da0c6bd0b80dc6c9e37a525a37258518c293 (diff) | |
Merge pull request #380 from toasted-nutbread/anki-templates-file
Load default Anki field templates from a file
| -rw-r--r-- | ext/bg/data/default-anki-field-templates.handlebars | 161 | ||||
| -rw-r--r-- | ext/bg/js/backend.js | 20 | ||||
| -rw-r--r-- | ext/bg/js/options.js | 177 | ||||
| -rw-r--r-- | ext/bg/js/settings/anki-templates.js | 16 | ||||
| -rw-r--r-- | ext/bg/js/settings/backup.js | 8 | ||||
| -rw-r--r-- | ext/mixed/js/api.js | 4 | 
6 files changed, 191 insertions, 195 deletions
| diff --git a/ext/bg/data/default-anki-field-templates.handlebars b/ext/bg/data/default-anki-field-templates.handlebars new file mode 100644 index 00000000..0442f7c5 --- /dev/null +++ b/ext/bg/data/default-anki-field-templates.handlebars @@ -0,0 +1,161 @@ +{{#*inline "glossary-single"}} +    {{~#unless brief~}} +        {{~#if definitionTags~}}<i>({{#each definitionTags}}{{name}}{{#unless @last}}, {{/unless}}{{/each}})</i> {{/if~}} +        {{~#if only~}}({{#each only}}{{{.}}}{{#unless @last}}, {{/unless}}{{/each}} only) {{/if~}} +    {{~/unless~}} +    {{~#if glossary.[1]~}} +        {{~#if compactGlossaries~}} +            {{#each glossary}}{{#multiLine}}{{.}}{{/multiLine}}{{#unless @last}} | {{/unless}}{{/each}} +        {{~else~}} +            <ul>{{#each glossary}}<li>{{#multiLine}}{{.}}{{/multiLine}}</li>{{/each}}</ul> +        {{~/if~}} +    {{~else~}} +        {{~#multiLine}}{{glossary.[0]}}{{/multiLine~}} +    {{~/if~}} +{{/inline}} + +{{#*inline "audio"}}{{/inline}} + +{{#*inline "character"}} +    {{~definition.character~}} +{{/inline}} + +{{#*inline "dictionary"}} +    {{~definition.dictionary~}} +{{/inline}} + +{{#*inline "expression"}} +    {{~#if merge~}} +        {{~#if modeTermKana~}} +            {{~#each definition.reading~}} +                {{{.}}} +                {{~#unless @last}}、{{/unless~}} +            {{~else~}} +                {{~#each definition.expression~}} +                    {{{.}}} +                    {{~#unless @last}}、{{/unless~}} +                {{~/each~}} +            {{~/each~}} +        {{~else~}} +            {{~#each definition.expression~}} +                {{{.}}} +                {{~#unless @last}}、{{/unless~}} +            {{~/each~}} +        {{~/if~}} +    {{~else~}} +        {{~#if modeTermKana~}} +            {{~#if definition.reading~}} +                {{definition.reading}} +            {{~else~}} +                {{definition.expression}} +            {{~/if~}} +        {{~else~}} +            {{definition.expression}} +        {{~/if~}} +    {{~/if~}} +{{/inline}} + +{{#*inline "furigana"}} +    {{~#if merge~}} +        {{~#each definition.expressions~}} +            <span class="expression-{{termFrequency}}">{{~#furigana}}{{{.}}}{{/furigana~}}</span> +            {{~#unless @last}}、{{/unless~}} +        {{~/each~}} +    {{~else~}} +        {{#furigana}}{{{definition}}}{{/furigana}} +    {{~/if~}} +{{/inline}} + +{{#*inline "furigana-plain"}} +    {{~#if merge~}} +        {{~#each definition.expressions~}} +            <span class="expression-{{termFrequency}}">{{~#furiganaPlain}}{{{.}}}{{/furiganaPlain~}}</span> +            {{~#unless @last}}、{{/unless~}} +        {{~/each~}} +    {{~else~}} +        {{#furiganaPlain}}{{{definition}}}{{/furiganaPlain}} +    {{~/if~}} +{{/inline}} + +{{#*inline "glossary"}} +    <div style="text-align: left;"> +    {{~#if modeKanji~}} +        {{~#if definition.glossary.[1]~}} +            <ol>{{#each definition.glossary}}<li>{{.}}</li>{{/each}}</ol> +        {{~else~}} +            {{definition.glossary.[0]}} +        {{~/if~}} +    {{~else~}} +        {{~#if group~}} +            {{~#if definition.definitions.[1]~}} +                <ol>{{#each definition.definitions}}<li>{{> glossary-single brief=../brief compactGlossaries=../compactGlossaries}}</li>{{/each}}</ol> +            {{~else~}} +                {{~> glossary-single definition.definitions.[0] brief=brief compactGlossaries=compactGlossaries~}} +            {{~/if~}} +        {{~else if merge~}} +            {{~#if definition.definitions.[1]~}} +                <ol>{{#each definition.definitions}}<li>{{> glossary-single brief=../brief compactGlossaries=../compactGlossaries}}</li>{{/each}}</ol> +            {{~else~}} +                {{~> glossary-single definition.definitions.[0] brief=brief compactGlossaries=compactGlossaries~}} +            {{~/if~}} +        {{~else~}} +            {{~> glossary-single definition brief=brief compactGlossaries=compactGlossaries~}} +        {{~/if~}} +    {{~/if~}} +    </div> +{{/inline}} + +{{#*inline "glossary-brief"}} +    {{~> glossary brief=true ~}} +{{/inline}} + +{{#*inline "kunyomi"}} +    {{~#each definition.kunyomi}}{{.}}{{#unless @last}}, {{/unless}}{{/each~}} +{{/inline}} + +{{#*inline "onyomi"}} +    {{~#each definition.onyomi}}{{.}}{{#unless @last}}, {{/unless}}{{/each~}} +{{/inline}} + +{{#*inline "reading"}} +    {{~#unless modeTermKana~}} +        {{~#if merge~}} +            {{~#each definition.reading~}} +                {{{.}}} +                {{~#unless @last}}、{{/unless~}} +            {{~/each~}} +        {{~else~}} +            {{~definition.reading~}} +        {{~/if~}} +    {{~/unless~}} +{{/inline}} + +{{#*inline "sentence"}} +    {{~#if definition.cloze}}{{definition.cloze.sentence}}{{/if~}} +{{/inline}} + +{{#*inline "cloze-prefix"}} +    {{~#if definition.cloze}}{{definition.cloze.prefix}}{{/if~}} +{{/inline}} + +{{#*inline "cloze-body"}} +    {{~#if definition.cloze}}{{definition.cloze.body}}{{/if~}} +{{/inline}} + +{{#*inline "cloze-suffix"}} +    {{~#if definition.cloze}}{{definition.cloze.suffix}}{{/if~}} +{{/inline}} + +{{#*inline "tags"}} +    {{~#each definition.definitionTags}}{{name}}{{#unless @last}}, {{/unless}}{{/each~}} +{{/inline}} + +{{#*inline "url"}} +    <a href="{{definition.url}}">{{definition.url}}</a> +{{/inline}} + +{{#*inline "screenshot"}} +    <img src="{{definition.screenshotFileName}}" /> +{{/inline}} + +{{~> (lookup . "marker") ~}}
\ No newline at end of file diff --git a/ext/bg/js/backend.js b/ext/bg/js/backend.js index 238ac52c..b99d1ca4 100644 --- a/ext/bg/js/backend.js +++ b/ext/bg/js/backend.js @@ -17,7 +17,7 @@   */  /*global optionsSave, utilIsolate -conditionsTestValue, profileConditionsDescriptor, profileOptionsGetDefaultFieldTemplates +conditionsTestValue, profileConditionsDescriptor  handlebarsRenderDynamic  requestText, requestJson, optionsLoad  dictConfigured, dictTermsSort, dictEnabledSet, dictNoteFormat @@ -33,6 +33,7 @@ class Backend {          this.clipboardMonitor = new ClipboardMonitor();          this.options = null;          this.optionsSchema = null; +        this.defaultAnkiFieldTemplates = null;          this.optionsContext = {              depth: 0,              url: window.location.href @@ -74,7 +75,8 @@ class Backend {              ['getDisplayTemplatesHtml', this._onApiGetDisplayTemplatesHtml.bind(this)],              ['getQueryParserTemplatesHtml', this._onApiGetQueryParserTemplatesHtml.bind(this)],              ['getZoom', this._onApiGetZoom.bind(this)], -            ['getMessageToken', this._onApiGetMessageToken.bind(this)] +            ['getMessageToken', this._onApiGetMessageToken.bind(this)], +            ['getDefaultAnkiFieldTemplates', this._onApiGetDefaultAnkiFieldTemplates.bind(this)]          ]);          this._commandHandlers = new Map([ @@ -89,6 +91,7 @@ class Backend {          await this.translator.prepare();          this.optionsSchema = await requestJson(chrome.runtime.getURL('/bg/data/options-schema.json'), 'GET'); +        this.defaultAnkiFieldTemplates = await requestText(chrome.runtime.getURL('/bg/data/default-anki-field-templates.handlebars'), 'GET');          this.options = await optionsLoad();          try {              this.options = JsonSchema.getValidValueOrDefault(this.optionsSchema, this.options); @@ -423,7 +426,7 @@ class Backend {      async _onApiDefinitionAdd({definition, mode, context, optionsContext}) {          const options = await this.getOptions(optionsContext); -        const templates = Backend._getTemplates(options); +        const templates = this.defaultAnkiFieldTemplates;          if (mode !== 'kanji') {              await audioInject( @@ -448,7 +451,7 @@ class Backend {      async _onApiDefinitionsAddable({definitions, modes, optionsContext}) {          const options = await this.getOptions(optionsContext); -        const templates = Backend._getTemplates(options); +        const templates = this.defaultAnkiFieldTemplates;          const states = [];          try { @@ -656,6 +659,10 @@ class Backend {          return this.messageToken;      } +    async _onApiGetDefaultAnkiFieldTemplates() { +        return this.defaultAnkiFieldTemplates; +    } +      // Command handlers      async _onCommandSearch(params) { @@ -896,11 +903,6 @@ class Backend {              return 'chrome';          }      } - -    static _getTemplates(options) { -        const templates = options.anki.fieldTemplates; -        return typeof templates === 'string' ? templates : profileOptionsGetDefaultFieldTemplates(); -    }  }  window.yomichanBackend = new Backend(); diff --git a/ext/bg/js/options.js b/ext/bg/js/options.js index f9db99a2..879b4a59 100644 --- a/ext/bg/js/options.js +++ b/ext/bg/js/options.js @@ -58,22 +58,17 @@ const profileOptionsVersionUpdates = [          options.scanning.modifier = options.scanning.requireShift ? 'shift' : 'none';      },      (options) => { -        const fieldTemplatesDefault = profileOptionsGetDefaultFieldTemplates();          options.general.resultOutputMode = options.general.groupResults ? 'group' : 'split'; -        options.anki.fieldTemplates = ( -            (utilStringHashCode(options.anki.fieldTemplates) !== -805327496) ? -            `{{#if merge}}${fieldTemplatesDefault}{{else}}${options.anki.fieldTemplates}{{/if}}` : -            fieldTemplatesDefault -        ); +        options.anki.fieldTemplates = null;      },      (options) => {          if (utilStringHashCode(options.anki.fieldTemplates) === 1285806040) { -            options.anki.fieldTemplates = profileOptionsGetDefaultFieldTemplates(); +            options.anki.fieldTemplates = null;          }      },      (options) => {          if (utilStringHashCode(options.anki.fieldTemplates) === -250091611) { -            options.anki.fieldTemplates = profileOptionsGetDefaultFieldTemplates(); +            options.anki.fieldTemplates = null;          }      },      (options) => { @@ -97,172 +92,6 @@ const profileOptionsVersionUpdates = [      }  ]; -function profileOptionsGetDefaultFieldTemplates() { -    return ` -{{#*inline "glossary-single"}} -    {{~#unless brief~}} -        {{~#if definitionTags~}}<i>({{#each definitionTags}}{{name}}{{#unless @last}}, {{/unless}}{{/each}})</i> {{/if~}} -        {{~#if only~}}({{#each only}}{{{.}}}{{#unless @last}}, {{/unless}}{{/each}} only) {{/if~}} -    {{~/unless~}} -    {{~#if glossary.[1]~}} -        {{~#if compactGlossaries~}} -            {{#each glossary}}{{#multiLine}}{{.}}{{/multiLine}}{{#unless @last}} | {{/unless}}{{/each}} -        {{~else~}} -            <ul>{{#each glossary}}<li>{{#multiLine}}{{.}}{{/multiLine}}</li>{{/each}}</ul> -        {{~/if~}} -    {{~else~}} -        {{~#multiLine}}{{glossary.[0]}}{{/multiLine~}} -    {{~/if~}} -{{/inline}} - -{{#*inline "audio"}}{{/inline}} - -{{#*inline "character"}} -    {{~definition.character~}} -{{/inline}} - -{{#*inline "dictionary"}} -    {{~definition.dictionary~}} -{{/inline}} - -{{#*inline "expression"}} -    {{~#if merge~}} -        {{~#if modeTermKana~}} -            {{~#each definition.reading~}} -                {{{.}}} -                {{~#unless @last}}、{{/unless~}} -            {{~else~}} -                {{~#each definition.expression~}} -                    {{{.}}} -                    {{~#unless @last}}、{{/unless~}} -                {{~/each~}} -            {{~/each~}} -        {{~else~}} -            {{~#each definition.expression~}} -                {{{.}}} -                {{~#unless @last}}、{{/unless~}} -            {{~/each~}} -        {{~/if~}} -    {{~else~}} -        {{~#if modeTermKana~}} -            {{~#if definition.reading~}} -                {{definition.reading}} -            {{~else~}} -                {{definition.expression}} -            {{~/if~}} -        {{~else~}} -            {{definition.expression}} -        {{~/if~}} -    {{~/if~}} -{{/inline}} - -{{#*inline "furigana"}} -    {{~#if merge~}} -        {{~#each definition.expressions~}} -            <span class="expression-{{termFrequency}}">{{~#furigana}}{{{.}}}{{/furigana~}}</span> -            {{~#unless @last}}、{{/unless~}} -        {{~/each~}} -    {{~else~}} -        {{#furigana}}{{{definition}}}{{/furigana}} -    {{~/if~}} -{{/inline}} - -{{#*inline "furigana-plain"}} -    {{~#if merge~}} -        {{~#each definition.expressions~}} -            <span class="expression-{{termFrequency}}">{{~#furiganaPlain}}{{{.}}}{{/furiganaPlain~}}</span> -            {{~#unless @last}}、{{/unless~}} -        {{~/each~}} -    {{~else~}} -        {{#furiganaPlain}}{{{definition}}}{{/furiganaPlain}} -    {{~/if~}} -{{/inline}} - -{{#*inline "glossary"}} -    <div style="text-align: left;"> -    {{~#if modeKanji~}} -        {{~#if definition.glossary.[1]~}} -            <ol>{{#each definition.glossary}}<li>{{.}}</li>{{/each}}</ol> -        {{~else~}} -            {{definition.glossary.[0]}} -        {{~/if~}} -    {{~else~}} -        {{~#if group~}} -            {{~#if definition.definitions.[1]~}} -                <ol>{{#each definition.definitions}}<li>{{> glossary-single brief=../brief compactGlossaries=../compactGlossaries}}</li>{{/each}}</ol> -            {{~else~}} -                {{~> glossary-single definition.definitions.[0] brief=brief compactGlossaries=compactGlossaries~}} -            {{~/if~}} -        {{~else if merge~}} -            {{~#if definition.definitions.[1]~}} -                <ol>{{#each definition.definitions}}<li>{{> glossary-single brief=../brief compactGlossaries=../compactGlossaries}}</li>{{/each}}</ol> -            {{~else~}} -                {{~> glossary-single definition.definitions.[0] brief=brief compactGlossaries=compactGlossaries~}} -            {{~/if~}} -        {{~else~}} -            {{~> glossary-single definition brief=brief compactGlossaries=compactGlossaries~}} -        {{~/if~}} -    {{~/if~}} -    </div> -{{/inline}} - -{{#*inline "glossary-brief"}} -    {{~> glossary brief=true ~}} -{{/inline}} - -{{#*inline "kunyomi"}} -    {{~#each definition.kunyomi}}{{.}}{{#unless @last}}, {{/unless}}{{/each~}} -{{/inline}} - -{{#*inline "onyomi"}} -    {{~#each definition.onyomi}}{{.}}{{#unless @last}}, {{/unless}}{{/each~}} -{{/inline}} - -{{#*inline "reading"}} -    {{~#unless modeTermKana~}} -        {{~#if merge~}} -            {{~#each definition.reading~}} -                {{{.}}} -                {{~#unless @last}}、{{/unless~}} -            {{~/each~}} -        {{~else~}} -            {{~definition.reading~}} -        {{~/if~}} -    {{~/unless~}} -{{/inline}} - -{{#*inline "sentence"}} -    {{~#if definition.cloze}}{{definition.cloze.sentence}}{{/if~}} -{{/inline}} - -{{#*inline "cloze-prefix"}} -    {{~#if definition.cloze}}{{definition.cloze.prefix}}{{/if~}} -{{/inline}} - -{{#*inline "cloze-body"}} -    {{~#if definition.cloze}}{{definition.cloze.body}}{{/if~}} -{{/inline}} - -{{#*inline "cloze-suffix"}} -    {{~#if definition.cloze}}{{definition.cloze.suffix}}{{/if~}} -{{/inline}} - -{{#*inline "tags"}} -    {{~#each definition.definitionTags}}{{name}}{{#unless @last}}, {{/unless}}{{/each~}} -{{/inline}} - -{{#*inline "url"}} -    <a href="{{definition.url}}">{{definition.url}}</a> -{{/inline}} - -{{#*inline "screenshot"}} -    <img src="{{definition.screenshotFileName}}" /> -{{/inline}} - -{{~> (lookup . "marker") ~}} -`.trim(); -} -  function profileOptionsCreateDefaults() {      return {          general: { diff --git a/ext/bg/js/settings/anki-templates.js b/ext/bg/js/settings/anki-templates.js index 770716d4..244ec42e 100644 --- a/ext/bg/js/settings/anki-templates.js +++ b/ext/bg/js/settings/anki-templates.js @@ -17,21 +17,23 @@   */  /*global getOptionsContext, getOptionsMutable, settingsSaveOptions -profileOptionsGetDefaultFieldTemplates, ankiGetFieldMarkers, ankiGetFieldMarkersHtml, dictFieldFormat -apiOptionsGet, apiTermsFind*/ +ankiGetFieldMarkers, ankiGetFieldMarkersHtml, dictFieldFormat +apiOptionsGet, apiTermsFind, apiGetDefaultAnkiFieldTemplates*/  function onAnkiFieldTemplatesReset(e) {      e.preventDefault();      $('#field-template-reset-modal').modal('show');  } -function onAnkiFieldTemplatesResetConfirm(e) { +async function onAnkiFieldTemplatesResetConfirm(e) {      e.preventDefault();      $('#field-template-reset-modal').modal('hide'); +    const value = await apiGetDefaultAnkiFieldTemplates(); +      const element = document.querySelector('#field-templates'); -    element.value = profileOptionsGetDefaultFieldTemplates(); +    element.value = value;      element.dispatchEvent(new Event('change'));  } @@ -57,7 +59,7 @@ async function ankiTemplatesUpdateValue() {      const optionsContext = getOptionsContext();      const options = await apiOptionsGet(optionsContext);      let templates = options.anki.fieldTemplates; -    if (typeof templates !== 'string') { templates = profileOptionsGetDefaultFieldTemplates(); } +    if (typeof templates !== 'string') { templates = await apiGetDefaultAnkiFieldTemplates(); }      $('#field-templates').val(templates);      onAnkiTemplatesValidateCompile(); @@ -89,7 +91,7 @@ async function ankiTemplatesValidate(infoNode, field, mode, showSuccessResult, i          if (definition !== null) {              const options = await apiOptionsGet(optionsContext);              let templates = options.anki.fieldTemplates; -            if (typeof templates !== 'string') { templates = profileOptionsGetDefaultFieldTemplates(); } +            if (typeof templates !== 'string') { templates = await apiGetDefaultAnkiFieldTemplates(); }              result = await dictFieldFormat(field, definition, mode, options, templates, exceptions);          }      } catch (e) { @@ -109,7 +111,7 @@ async function ankiTemplatesValidate(infoNode, field, mode, showSuccessResult, i  async function onAnkiFieldTemplatesChanged(e) {      // Get value      let templates = e.currentTarget.value; -    if (templates === profileOptionsGetDefaultFieldTemplates()) { +    if (templates === await apiGetDefaultAnkiFieldTemplates()) {          // Default          templates = null;      } diff --git a/ext/bg/js/settings/backup.js b/ext/bg/js/settings/backup.js index f4d622a4..e945d186 100644 --- a/ext/bg/js/settings/backup.js +++ b/ext/bg/js/settings/backup.js @@ -16,10 +16,9 @@   * along with this program.  If not, see <https://www.gnu.org/licenses/>.   */ -/*global apiOptionsGetFull, apiGetEnvironmentInfo +/*global apiOptionsGetFull, apiGetEnvironmentInfo, apiGetDefaultAnkiFieldTemplates  utilBackend, utilIsolate, utilBackgroundIsolate, utilReadFileArrayBuffer -optionsGetDefault, optionsUpdateVersion -profileOptionsGetDefaultFieldTemplates*/ +optionsGetDefault, optionsUpdateVersion*/  // Exporting @@ -47,8 +46,7 @@ function _getSettingsExportDateString(date, dateSeparator, dateTimeSeparator, ti  async function _getSettingsExportData(date) {      const optionsFull = await apiOptionsGetFull();      const environment = await apiGetEnvironmentInfo(); - -    const fieldTemplatesDefault = profileOptionsGetDefaultFieldTemplates(); +    const fieldTemplatesDefault = await apiGetDefaultAnkiFieldTemplates();      // Format options      for (const {options} of optionsFull.profiles) { diff --git a/ext/mixed/js/api.js b/ext/mixed/js/api.js index 7ea68d59..26f4389d 100644 --- a/ext/mixed/js/api.js +++ b/ext/mixed/js/api.js @@ -117,6 +117,10 @@ function apiGetMessageToken() {      return _apiInvoke('getMessageToken');  } +function apiGetDefaultAnkiFieldTemplates() { +    return _apiInvoke('getDefaultAnkiFieldTemplates'); +} +  function _apiInvoke(action, params={}) {      const data = {action, params};      return new Promise((resolve, reject) => { |