Load default Anki field templates from a file

This commit is contained in:
toasted-nutbread 2020-02-27 20:33:13 -05:00
parent fdfc2d33bb
commit 8e29da0c6b
6 changed files with 191 additions and 195 deletions

View File

@ -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") ~}}

View File

@ -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();

View File

@ -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: {

View File

@ -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;
}

View File

@ -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) {

View File

@ -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) => {