diff options
| author | toasted-nutbread <toasted-nutbread@users.noreply.github.com> | 2020-08-01 16:23:33 -0400 | 
|---|---|---|
| committer | GitHub <noreply@github.com> | 2020-08-01 16:23:33 -0400 | 
| commit | 838fd211c6737ce7e2b6802a43837cf4300b60d2 (patch) | |
| tree | 24fb7fd7d8e6c494a3e51defc7f32a6c3aa73107 /ext | |
| parent | 1e839cd230e53f822478f945cb415a8af2b09aef (diff) | |
Pitch accent Anki field templates (#701)
* Template helper updates
* Add pitch data to exported field formatting data
* Reuse note data
* Add no-op
* Set up pitch accent templates
* Refactor version update functions
* Implement upgrade process for new Anki templates
* Consistency
* Update README and anki.js to have matching markers
Diffstat (limited to 'ext')
| -rw-r--r-- | ext/bg/background.html | 1 | ||||
| -rw-r--r-- | ext/bg/data/anki-field-templates-upgrade-v2.handlebars | 109 | ||||
| -rw-r--r-- | ext/bg/data/default-anki-field-templates.handlebars | 110 | ||||
| -rw-r--r-- | ext/bg/js/anki-note-builder.js | 18 | ||||
| -rw-r--r-- | ext/bg/js/options.js | 94 | ||||
| -rw-r--r-- | ext/bg/js/settings/anki-templates.js | 3 | ||||
| -rw-r--r-- | ext/bg/js/settings/anki.js | 6 | ||||
| -rw-r--r-- | ext/bg/js/template-renderer.js | 55 | ||||
| -rw-r--r-- | ext/bg/settings.html | 1 | 
9 files changed, 357 insertions, 40 deletions
| diff --git a/ext/bg/background.html b/ext/bg/background.html index a30b55a5..73dbc251 100644 --- a/ext/bg/background.html +++ b/ext/bg/background.html @@ -46,6 +46,7 @@          <script src="/bg/js/translator.js"></script>          <script src="/bg/js/util.js"></script>          <script src="/mixed/js/audio-system.js"></script> +        <script src="/mixed/js/dictionary-data-util.js"></script>          <script src="/mixed/js/object-property-accessor.js"></script>          <script src="/bg/js/background-main.js"></script> diff --git a/ext/bg/data/anki-field-templates-upgrade-v2.handlebars b/ext/bg/data/anki-field-templates-upgrade-v2.handlebars new file mode 100644 index 00000000..c018094e --- /dev/null +++ b/ext/bg/data/anki-field-templates-upgrade-v2.handlebars @@ -0,0 +1,109 @@ +{{! Pitch Accents }} +{{#*inline "pitch-accent-item-downstep-notation"}} +    {{~#scope~}} +        <span> +        {{~#set "style1a"~}}display:inline-block;position:relative;{{~/set~}} +        {{~#set "style1b"~}}padding-right:0.1em;margin-right:0.1em;{{~/set~}} +        {{~#set "style2a"~}}display:block;user-select:none;pointer-events:none;position:absolute;top:0.1em;left:0;right:0;height:0;border-top:0.1em solid;{{~/set~}} +        {{~#set "style2b"~}}right:-0.1em;height:0.4em;border-right:0.1em solid;{{~/set~}} +        {{~#each (getKanaMorae reading)~}} +            {{~#set "style1"}}{{#get "style1a"}}{{/get}}{{/set~}} +            {{~#set "style2"}}{{/set~}} +            {{~#if (isMoraPitchHigh @index ../position)}} +                {{~#set "style2"}}{{#get "style2a"}}{{/get}}{{/set~}} +                {{~#if (op "!" (isMoraPitchHigh (op "+" @index 1) ../position))~}} +                    {{~#set "style1" (op "+" (get "style1") (get "style1b"))}}{{/set~}} +                    {{~#set "style2" (op "+" (get "style2") (get "style2b"))}}{{/set~}} +                {{~/if~}} +            {{~/if~}} +            <span style="{{#get "style1"}}{{/get}}">{{{.}}}<span style="{{#get "style2"}}{{/get}}"></span></span> +        {{~/each~}} +        </span> +    {{~/scope~}} +{{/inline}} + +{{#*inline "pitch-accent-item-graph-position-x"}}{{#op "+" 25 (op "*" index 50)}}{{/op}}{{/inline}} +{{#*inline "pitch-accent-item-graph-position-y"}}{{#op "+" 25 (op "?:" (isMoraPitchHigh index position) 0 50)}}{{/op}}{{/inline}} +{{#*inline "pitch-accent-item-graph-position"}}{{> pitch-accent-item-graph-position-x index=index position=position}} {{> pitch-accent-item-graph-position-y index=index position=position}}{{/inline}} +{{#*inline "pitch-accent-item-graph"}} +    {{~#scope~}} +        {{~#set "morae" (getKanaMorae reading)}}{{/set~}} +        {{~#set "morae-count" (property (get "morae") "length")}}{{/set~}} +<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 {{#op "+" 50 (op "*" 50 (get "morae-count"))}}{{/op}} 100" style="display:inline-block;height:2em;"> +    <defs> +        <g id="term-pitch-accent-graph-dot"><circle cx="0" cy="0" r="15" style="fill:#000;stroke:#000;stroke-width:5;" /></g> +        <g id="term-pitch-accent-graph-dot-downstep"><circle cx="0" cy="0" r="15" style="fill:none;stroke:#000;stroke-width:5;" /><circle cx="0" cy="0" r="5" style="fill:none;stroke:#000;stroke-width:5;" /></g> +        <g id="term-pitch-accent-graph-triangle"><path d="M0 13 L15 -13 L-15 -13 Z" style="fill:none;stroke:#000;stroke-width:5;" /></g> +    </defs> +    <path style="fill:none;stroke:#000;stroke-width:5;" d=" +    {{~#set "cmd" "M"}}{{/set~}} +    {{~#each (get "morae")~}} +        {{~#get "cmd"}}{{/get~}} +        {{~> pitch-accent-item-graph-position index=@index position=../position~}} +        {{~#set "cmd" "L"}}{{/set~}} +    {{~/each~}} +    "></path> +    <path style="fill:none;stroke:#000;stroke-width:5;stroke-dasharray:5 5;" d="M{{> pitch-accent-item-graph-position index=(op "-" (get "morae-count") 1) position=position}} L{{> pitch-accent-item-graph-position index=(get "morae-count") position=position}}"></path> +    {{#each (get "morae")}} +    <use href="{{#if (op "&&" (isMoraPitchHigh @index ../position) (op "!" (isMoraPitchHigh (op "+" @index 1) ../position)))}}#term-pitch-accent-graph-dot-downstep{{else}}#term-pitch-accent-graph-dot{{/if}}" x="{{> pitch-accent-item-graph-position-x index=@index position=../position}}" y="{{> pitch-accent-item-graph-position-y index=@index position=../position}}"></use> +    {{/each}} +    <use href="#term-pitch-accent-graph-triangle" x="{{> pitch-accent-item-graph-position-x index=(get "morae-count") position=position}}" y="{{> pitch-accent-item-graph-position-y index=(get "morae-count") position=position}}"></use> +</svg> +    {{~/scope~}} +{{/inline}} + +{{#*inline "pitch-accent-item-position"~}} +    <span>[{{position}}]</span> +{{~/inline}} + +{{#*inline "pitch-accent-item"}} +    {{~#if (op "==" format "downstep-notation")~}} +        {{~> pitch-accent-item-downstep-notation~}} +    {{~else if (op "==" format "graph")~}} +        {{~> pitch-accent-item-graph~}} +    {{~else if (op "==" format "position")~}} +        {{~> pitch-accent-item-position~}} +    {{~/if~}} +{{/inline}} + +{{#*inline "pitch-accent-item-disambiguation"}} +    {{~#scope~}} +        {{~#set "exclusive" (spread exclusiveExpressions exclusiveReadings)}}{{/set~}} +        {{~#if (op ">" (property (get "exclusive") "length") 0)~}} +            {{~#set "separator" ""~}}{{/set~}} +            <em>({{#each (get "exclusive")~}} +                {{~#get "separator"}}{{/get~}}{{{.}}} +            {{~/each}} only) </em> +        {{~/if~}} +    {{~/scope~}} +{{/inline}} + +{{#*inline "pitch-accent-list"}} +    {{~#if (op ">" pitchCount 0)~}} +        {{~#if (op ">" pitchCount 1)~}}<ol>{{~/if~}} +        {{~#each pitches~}} +            {{~#each pitches~}} +                {{~#if (op ">" ../../pitchCount 1)~}}<li>{{~/if~}} +                    {{~> pitch-accent-item-disambiguation~}} +                    {{~> pitch-accent-item format=../../format~}} +                {{~#if (op ">" ../../pitchCount 1)~}}</li>{{~/if~}} +            {{~/each~}} +        {{~/each~}} +        {{~#if (op ">" pitchCount 1)~}}</ol>{{~/if~}} +    {{~else~}} +        No pitch accent data +    {{~/if~}} +{{/inline}} + +{{#*inline "pitch-accents"}} +    {{~> pitch-accent-list format='downstep-notation'~}} +{{/inline}} + +{{#*inline "pitch-accent-graphs"}} +    {{~> pitch-accent-list format='graph'~}} +{{/inline}} + +{{#*inline "pitch-accent-positions"}} +    {{~> pitch-accent-list format='position'~}} +{{/inline}} +{{! End Pitch Accents }} diff --git a/ext/bg/data/default-anki-field-templates.handlebars b/ext/bg/data/default-anki-field-templates.handlebars index 42deae23..b348042c 100644 --- a/ext/bg/data/default-anki-field-templates.handlebars +++ b/ext/bg/data/default-anki-field-templates.handlebars @@ -166,4 +166,114 @@      {{~context.document.title~}}  {{/inline}} +{{! Pitch Accents }} +{{#*inline "pitch-accent-item-downstep-notation"}} +    {{~#scope~}} +        <span> +        {{~#set "style1a"~}}display:inline-block;position:relative;{{~/set~}} +        {{~#set "style1b"~}}padding-right:0.1em;margin-right:0.1em;{{~/set~}} +        {{~#set "style2a"~}}display:block;user-select:none;pointer-events:none;position:absolute;top:0.1em;left:0;right:0;height:0;border-top:0.1em solid;{{~/set~}} +        {{~#set "style2b"~}}right:-0.1em;height:0.4em;border-right:0.1em solid;{{~/set~}} +        {{~#each (getKanaMorae reading)~}} +            {{~#set "style1"}}{{#get "style1a"}}{{/get}}{{/set~}} +            {{~#set "style2"}}{{/set~}} +            {{~#if (isMoraPitchHigh @index ../position)}} +                {{~#set "style2"}}{{#get "style2a"}}{{/get}}{{/set~}} +                {{~#if (op "!" (isMoraPitchHigh (op "+" @index 1) ../position))~}} +                    {{~#set "style1" (op "+" (get "style1") (get "style1b"))}}{{/set~}} +                    {{~#set "style2" (op "+" (get "style2") (get "style2b"))}}{{/set~}} +                {{~/if~}} +            {{~/if~}} +            <span style="{{#get "style1"}}{{/get}}">{{{.}}}<span style="{{#get "style2"}}{{/get}}"></span></span> +        {{~/each~}} +        </span> +    {{~/scope~}} +{{/inline}} + +{{#*inline "pitch-accent-item-graph-position-x"}}{{#op "+" 25 (op "*" index 50)}}{{/op}}{{/inline}} +{{#*inline "pitch-accent-item-graph-position-y"}}{{#op "+" 25 (op "?:" (isMoraPitchHigh index position) 0 50)}}{{/op}}{{/inline}} +{{#*inline "pitch-accent-item-graph-position"}}{{> pitch-accent-item-graph-position-x index=index position=position}} {{> pitch-accent-item-graph-position-y index=index position=position}}{{/inline}} +{{#*inline "pitch-accent-item-graph"}} +    {{~#scope~}} +        {{~#set "morae" (getKanaMorae reading)}}{{/set~}} +        {{~#set "morae-count" (property (get "morae") "length")}}{{/set~}} +<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 {{#op "+" 50 (op "*" 50 (get "morae-count"))}}{{/op}} 100" style="display:inline-block;height:2em;"> +    <defs> +        <g id="term-pitch-accent-graph-dot"><circle cx="0" cy="0" r="15" style="fill:#000;stroke:#000;stroke-width:5;" /></g> +        <g id="term-pitch-accent-graph-dot-downstep"><circle cx="0" cy="0" r="15" style="fill:none;stroke:#000;stroke-width:5;" /><circle cx="0" cy="0" r="5" style="fill:none;stroke:#000;stroke-width:5;" /></g> +        <g id="term-pitch-accent-graph-triangle"><path d="M0 13 L15 -13 L-15 -13 Z" style="fill:none;stroke:#000;stroke-width:5;" /></g> +    </defs> +    <path style="fill:none;stroke:#000;stroke-width:5;" d=" +    {{~#set "cmd" "M"}}{{/set~}} +    {{~#each (get "morae")~}} +        {{~#get "cmd"}}{{/get~}} +        {{~> pitch-accent-item-graph-position index=@index position=../position~}} +        {{~#set "cmd" "L"}}{{/set~}} +    {{~/each~}} +    "></path> +    <path style="fill:none;stroke:#000;stroke-width:5;stroke-dasharray:5 5;" d="M{{> pitch-accent-item-graph-position index=(op "-" (get "morae-count") 1) position=position}} L{{> pitch-accent-item-graph-position index=(get "morae-count") position=position}}"></path> +    {{#each (get "morae")}} +    <use href="{{#if (op "&&" (isMoraPitchHigh @index ../position) (op "!" (isMoraPitchHigh (op "+" @index 1) ../position)))}}#term-pitch-accent-graph-dot-downstep{{else}}#term-pitch-accent-graph-dot{{/if}}" x="{{> pitch-accent-item-graph-position-x index=@index position=../position}}" y="{{> pitch-accent-item-graph-position-y index=@index position=../position}}"></use> +    {{/each}} +    <use href="#term-pitch-accent-graph-triangle" x="{{> pitch-accent-item-graph-position-x index=(get "morae-count") position=position}}" y="{{> pitch-accent-item-graph-position-y index=(get "morae-count") position=position}}"></use> +</svg> +    {{~/scope~}} +{{/inline}} + +{{#*inline "pitch-accent-item-position"~}} +    <span>[{{position}}]</span> +{{~/inline}} + +{{#*inline "pitch-accent-item"}} +    {{~#if (op "==" format "downstep-notation")~}} +        {{~> pitch-accent-item-downstep-notation~}} +    {{~else if (op "==" format "graph")~}} +        {{~> pitch-accent-item-graph~}} +    {{~else if (op "==" format "position")~}} +        {{~> pitch-accent-item-position~}} +    {{~/if~}} +{{/inline}} + +{{#*inline "pitch-accent-item-disambiguation"}} +    {{~#scope~}} +        {{~#set "exclusive" (spread exclusiveExpressions exclusiveReadings)}}{{/set~}} +        {{~#if (op ">" (property (get "exclusive") "length") 0)~}} +            {{~#set "separator" ""~}}{{/set~}} +            <em>({{#each (get "exclusive")~}} +                {{~#get "separator"}}{{/get~}}{{{.}}} +            {{~/each}} only) </em> +        {{~/if~}} +    {{~/scope~}} +{{/inline}} + +{{#*inline "pitch-accent-list"}} +    {{~#if (op ">" pitchCount 0)~}} +        {{~#if (op ">" pitchCount 1)~}}<ol>{{~/if~}} +        {{~#each pitches~}} +            {{~#each pitches~}} +                {{~#if (op ">" ../../pitchCount 1)~}}<li>{{~/if~}} +                    {{~> pitch-accent-item-disambiguation~}} +                    {{~> pitch-accent-item format=../../format~}} +                {{~#if (op ">" ../../pitchCount 1)~}}</li>{{~/if~}} +            {{~/each~}} +        {{~/each~}} +        {{~#if (op ">" pitchCount 1)~}}</ol>{{~/if~}} +    {{~else~}} +        No pitch accent data +    {{~/if~}} +{{/inline}} + +{{#*inline "pitch-accents"}} +    {{~> pitch-accent-list format='downstep-notation'~}} +{{/inline}} + +{{#*inline "pitch-accent-graphs"}} +    {{~> pitch-accent-list format='graph'~}} +{{/inline}} + +{{#*inline "pitch-accent-positions"}} +    {{~> pitch-accent-list format='position'~}} +{{/inline}} +{{! End Pitch Accents }} +  {{~> (lookup . "marker") ~}} diff --git a/ext/bg/js/anki-note-builder.js b/ext/bg/js/anki-note-builder.js index 7fe8962a..2405543e 100644 --- a/ext/bg/js/anki-note-builder.js +++ b/ext/bg/js/anki-note-builder.js @@ -15,6 +15,10 @@   * along with this program.  If not, see <https://www.gnu.org/licenses/>.   */ +/* global + * DictionaryDataUtil + */ +  class AnkiNoteBuilder {      constructor({anki, audioSystem, renderTemplate}) {          this._anki = anki; @@ -39,9 +43,10 @@ class AnkiNoteBuilder {              }          }; +        const data = this.createNoteData(definition, mode, context, options);          const formattedFieldValuePromises = [];          for (const [, fieldValue] of modeOptionsFieldEntries) { -            const formattedFieldValuePromise = this.formatField(fieldValue, definition, mode, context, options, templates, null); +            const formattedFieldValuePromise = this.formatField(fieldValue, data, templates, null);              formattedFieldValuePromises.push(formattedFieldValuePromise);          } @@ -55,10 +60,14 @@ class AnkiNoteBuilder {          return note;      } -    async formatField(field, definition, mode, context, options, templates, errors=null) { -        const data = { +    createNoteData(definition, mode, context, options) { +        const pitches = DictionaryDataUtil.getPitchAccentInfos(definition); +        const pitchCount = pitches.reduce((i, v) => i + v.pitches.length, 0); +        return {              marker: null,              definition, +            pitches, +            pitchCount,              group: options.general.resultOutputMode === 'group',              merge: options.general.resultOutputMode === 'merge',              modeTermKanji: mode === 'term-kanji', @@ -67,6 +76,9 @@ class AnkiNoteBuilder {              compactGlossaries: options.general.compactGlossaries,              context          }; +    } + +    async formatField(field, data, templates, errors=null) {          const pattern = /\{([\w-]+)\}/g;          return await AnkiNoteBuilder.stringReplaceAsync(field, pattern, async (g0, marker) => {              data.marker = marker; diff --git a/ext/bg/js/options.js b/ext/bg/js/options.js index ffea96f8..0d83f428 100644 --- a/ext/bg/js/options.js +++ b/ext/bg/js/options.js @@ -380,31 +380,83 @@ class OptionsUtil {          return [              {                  async: false, -                update: (options) => { -                    // Version 1 changes: -                    //  Added options.global.database.prefixWildcardsSupported = false -                    options.global = { -                        database: { -                            prefixWildcardsSupported: false -                        } -                    }; -                    return options; -                } +                update: this._updateVersion1.bind(this)              },              {                  async: false, -                update: (options) => { -                    // Version 2 changes: -                    //  Legacy profile update process moved into this upgrade function. -                    for (const profile of options.profiles) { -                        if (!Array.isArray(profile.conditionGroups)) { -                            profile.conditionGroups = []; -                        } -                        profile.options = this._legacyProfileUpdateUpdateVersion(profile.options); -                    } -                    return options; -                } +                update: this._updateVersion2.bind(this) +            }, +            { +                async: true, +                update: this._updateVersion3.bind(this)              }          ];      } + +    static _updateVersion1(options) { +        // Version 1 changes: +        //  Added options.global.database.prefixWildcardsSupported = false. +        options.global = { +            database: { +                prefixWildcardsSupported: false +            } +        }; +        return options; +    } + +    static _updateVersion2(options) { +        // Version 2 changes: +        //  Legacy profile update process moved into this upgrade function. +        for (const profile of options.profiles) { +            if (!Array.isArray(profile.conditionGroups)) { +                profile.conditionGroups = []; +            } +            profile.options = this._legacyProfileUpdateUpdateVersion(profile.options); +        } +        return options; +    } + +    static async _updateVersion3(options) { +        // Version 3 changes: +        //  Pitch accent Anki field templates added. +        let addition = null; +        for (const {options: profileOptions} of options.profiles) { +            const fieldTemplates = profileOptions.anki.fieldTemplates; +            if (fieldTemplates !== null) { +                if (addition === null) { +                    addition = await this._updateVersion3GetAnkiFieldTemplates(); +                } +                profileOptions.anki.fieldTemplates = this._addFieldTemplatesBeforeEnd(fieldTemplates, addition); +            } +        } +        return options; +    } + +    static async _updateVersion3GetAnkiFieldTemplates() { +        const url = chrome.runtime.getURL('/bg/data/anki-field-templates-upgrade-v2.handlebars'); +        const response = await fetch(url, { +            method: 'GET', +            mode: 'no-cors', +            cache: 'default', +            credentials: 'omit', +            redirect: 'follow', +            referrerPolicy: 'no-referrer' +        }); +        return await response.text(); +    } + +    static async _addFieldTemplatesBeforeEnd(fieldTemplates, addition) { +        const pattern = /[ \t]*\{\{~?>\s*\(\s*lookup\s*\.\s*"marker"\s*\)\s*~?\}\}/; +        const newline = '\n'; +        let replaced = false; +        fieldTemplates = fieldTemplates.replace(pattern, (g0) => { +            replaced = true; +            return `${addition}${newline}${g0}`; +        }); +        if (!replaced) { +            fieldTemplates += newline; +            fieldTemplates += addition; +        } +        return fieldTemplates; +    }  } diff --git a/ext/bg/js/settings/anki-templates.js b/ext/bg/js/settings/anki-templates.js index 88d4fe04..4e004308 100644 --- a/ext/bg/js/settings/anki-templates.js +++ b/ext/bg/js/settings/anki-templates.js @@ -144,7 +144,8 @@ class AnkiTemplatesController {                  let templates = options.anki.fieldTemplates;                  if (typeof templates !== 'string') { templates = this._defaultFieldTemplates; }                  const ankiNoteBuilder = new AnkiNoteBuilder({renderTemplate: api.templateRender.bind(api)}); -                result = await ankiNoteBuilder.formatField(field, definition, mode, context, options, templates, exceptions); +                const data = ankiNoteBuilder.createNoteData(definition, mode, context, options); +                result = await ankiNoteBuilder.formatField(field, data, templates, exceptions);              }          } catch (e) {              exceptions.push(e); diff --git a/ext/bg/js/settings/anki.js b/ext/bg/js/settings/anki.js index 51dabba4..ac4c5455 100644 --- a/ext/bg/js/settings/anki.js +++ b/ext/bg/js/settings/anki.js @@ -54,6 +54,9 @@ class AnkiController {                      'furigana-plain',                      'glossary',                      'glossary-brief', +                    'pitch-accents', +                    'pitch-accent-graphs', +                    'pitch-accent-positions',                      'reading',                      'screenshot',                      'sentence', @@ -63,6 +66,9 @@ class AnkiController {              case 'kanji':                  return [                      'character', +                    'cloze-body', +                    'cloze-prefix', +                    'cloze-suffix',                      'dictionary',                      'document-title',                      'glossary', diff --git a/ext/bg/js/template-renderer.js b/ext/bg/js/template-renderer.js index ef05cbd8..59af74c8 100644 --- a/ext/bg/js/template-renderer.js +++ b/ext/bg/js/template-renderer.js @@ -82,7 +82,10 @@ class TemplateRenderer {              ['get',              this._get.bind(this)],              ['set',              this._set.bind(this)],              ['scope',            this._scope.bind(this)], -            ['isMoraPitchHigh',  this._isMoraPitchHigh.bind(this)] +            ['property',         this._property.bind(this)], +            ['noop',             this._noop.bind(this)], +            ['isMoraPitchHigh',  this._isMoraPitchHigh.bind(this)], +            ['getKanaMorae',     this._getKanaMorae.bind(this)]          ];          for (const [name, helper] of helpers) { @@ -316,21 +319,20 @@ class TemplateRenderer {      _set(context, ...args) {          switch (args.length) {              case 2: -            { -                const [key, options] = args; -                const value = options.fn(context); -                this._stateStack[this._stateStack.length - 1].set(key, value); -                return value; -            } +                { +                    const [key, options] = args; +                    const value = options.fn(context); +                    this._stateStack[this._stateStack.length - 1].set(key, value); +                } +                break;              case 3: -            { -                const [key, value] = args; -                this._stateStack[this._stateStack.length - 1].set(key, value); -                return value; -            } -            default: -                return void 0; +                { +                    const [key, value] = args; +                    this._stateStack[this._stateStack.length - 1].set(key, value); +                } +                break;          } +        return '';      }      _scope(context, options) { @@ -344,7 +346,30 @@ class TemplateRenderer {          }      } -    _isMoraPitchHigh(context, position, index) { +    _property(context, ...args) { +        const ii = args.length - 1; +        if (ii <= 0) { return void 0; } + +        try { +            let value = args[0]; +            for (let i = 1; i < ii; ++i) { +                value = value[args[i]]; +            } +            return value; +        } catch (e) { +            return void 0; +        } +    } + +    _noop(context, options) { +        return options.fn(context); +    } + +    _isMoraPitchHigh(context, index, position) {          return jp.isMoraPitchHigh(index, position);      } + +    _getKanaMorae(context, text) { +        return jp.getKanaMorae(`${text}`); +    }  } diff --git a/ext/bg/settings.html b/ext/bg/settings.html index 260c1b46..e29b1f45 100644 --- a/ext/bg/settings.html +++ b/ext/bg/settings.html @@ -1162,6 +1162,7 @@          <script src="/bg/js/settings/profiles.js"></script>          <script src="/bg/js/settings/settings-controller.js"></script>          <script src="/bg/js/settings/storage.js"></script> +        <script src="/mixed/js/dictionary-data-util.js"></script>          <script src="/mixed/js/object-property-accessor.js"></script>          <script src="/mixed/js/task-accumulator.js"></script>          <script src="/mixed/js/dom-data-binder.js"></script> |