aboutsummaryrefslogtreecommitdiff
path: root/test/test-options-util.js
diff options
context:
space:
mode:
authorDarius Jahandarie <djahandarie@gmail.com>2023-11-08 03:11:35 +0900
committerDarius Jahandarie <djahandarie@gmail.com>2023-11-08 03:23:17 +0900
commit0f4d36938fd0d844f548aa5a7f7e7842df8dfb41 (patch)
tree5b6be3620a557d0b9177047003f6d742d9d2a32d /test/test-options-util.js
parentef79eab44bfd000792c610b968b5ceefd41e76a0 (diff)
Switch to vitest for ESM support; other fixes
Diffstat (limited to 'test/test-options-util.js')
-rw-r--r--test/test-options-util.js1609
1 files changed, 0 insertions, 1609 deletions
diff --git a/test/test-options-util.js b/test/test-options-util.js
deleted file mode 100644
index d94028c0..00000000
--- a/test/test-options-util.js
+++ /dev/null
@@ -1,1609 +0,0 @@
-/*
- * Copyright (C) 2023 Yomitan Authors
- * Copyright (C) 2020-2022 Yomichan Authors
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <https://www.gnu.org/licenses/>.
- */
-
-const fs = require('fs');
-const url = require('url');
-const path = require('path');
-const assert = require('assert');
-const {testMain} = require('../dev/util');
-const {VM} = require('../dev/vm');
-
-
-function createVM(extDir) {
- const chrome = {
- runtime: {
- getURL(path2) {
- return url.pathToFileURL(path.join(extDir, path2.replace(/^\//, ''))).href;
- }
- }
- };
-
- async function fetch(url2) {
- const filePath = url.fileURLToPath(url2);
- await Promise.resolve();
- const content = fs.readFileSync(filePath, {encoding: null});
- return {
- ok: true,
- status: 200,
- statusText: 'OK',
- text: async () => Promise.resolve(content.toString('utf8')),
- json: async () => Promise.resolve(JSON.parse(content.toString('utf8')))
- };
- }
-
- const vm = new VM({chrome, fetch});
- vm.execute([
- 'js/core.js',
- 'js/general/cache-map.js',
- 'js/data/json-schema.js',
- 'js/templates/template-patcher.js',
- 'js/data/options-util.js'
- ]);
-
- return vm;
-}
-
-
-function clone(value) {
- return JSON.parse(JSON.stringify(value));
-}
-
-
-function createProfileOptionsTestData1() {
- return {
- version: 14,
- general: {
- enable: true,
- enableClipboardPopups: false,
- resultOutputMode: 'group',
- debugInfo: false,
- maxResults: 32,
- showAdvanced: false,
- popupDisplayMode: 'default',
- popupWidth: 400,
- popupHeight: 250,
- popupHorizontalOffset: 0,
- popupVerticalOffset: 10,
- popupHorizontalOffset2: 10,
- popupVerticalOffset2: 0,
- popupHorizontalTextPosition: 'below',
- popupVerticalTextPosition: 'before',
- popupScalingFactor: 1,
- popupScaleRelativeToPageZoom: false,
- popupScaleRelativeToVisualViewport: true,
- showGuide: true,
- compactTags: false,
- compactGlossaries: false,
- mainDictionary: '',
- popupTheme: 'default',
- popupOuterTheme: 'default',
- customPopupCss: '',
- customPopupOuterCss: '',
- enableWanakana: true,
- enableClipboardMonitor: false,
- showPitchAccentDownstepNotation: true,
- showPitchAccentPositionNotation: true,
- showPitchAccentGraph: false,
- showIframePopupsInRootFrame: false,
- useSecurePopupFrameUrl: true,
- usePopupShadowDom: true
- },
- audio: {
- enabled: true,
- sources: ['jpod101', 'text-to-speech', 'custom'],
- volume: 100,
- autoPlay: false,
- customSourceUrl: 'http://localhost/audio.mp3?term={expression}&reading={reading}',
- textToSpeechVoice: 'example-voice'
- },
- scanning: {
- middleMouse: true,
- touchInputEnabled: true,
- selectText: true,
- alphanumeric: true,
- autoHideResults: false,
- delay: 20,
- length: 10,
- modifier: 'shift',
- deepDomScan: false,
- popupNestingMaxDepth: 0,
- enablePopupSearch: false,
- enableOnPopupExpressions: false,
- enableOnSearchPage: true,
- enableSearchTags: false,
- layoutAwareScan: false
- },
- translation: {
- convertHalfWidthCharacters: 'false',
- convertNumericCharacters: 'false',
- convertAlphabeticCharacters: 'false',
- convertHiraganaToKatakana: 'false',
- convertKatakanaToHiragana: 'variant',
- collapseEmphaticSequences: 'false'
- },
- dictionaries: {
- 'Test Dictionary': {
- priority: 0,
- enabled: true,
- allowSecondarySearches: false
- }
- },
- parsing: {
- enableScanningParser: true,
- enableMecabParser: false,
- selectedParser: null,
- termSpacing: true,
- readingMode: 'hiragana'
- },
- anki: {
- enable: false,
- server: 'http://127.0.0.1:8765',
- tags: ['yomichan'],
- sentenceExt: 200,
- screenshot: {format: 'png', quality: 92},
- terms: {deck: '', model: '', fields: {}},
- kanji: {deck: '', model: '', fields: {}},
- duplicateScope: 'collection',
- fieldTemplates: null
- }
- };
-}
-
-function createOptionsTestData1() {
- return {
- profiles: [
- {
- name: 'Default',
- options: createProfileOptionsTestData1(),
- conditionGroups: [
- {
- conditions: [
- {
- type: 'popupLevel',
- operator: 'equal',
- value: 1
- },
- {
- type: 'popupLevel',
- operator: 'notEqual',
- value: 0
- },
- {
- type: 'popupLevel',
- operator: 'lessThan',
- value: 3
- },
- {
- type: 'popupLevel',
- operator: 'greaterThan',
- value: 0
- },
- {
- type: 'popupLevel',
- operator: 'lessThanOrEqual',
- value: 2
- },
- {
- type: 'popupLevel',
- operator: 'greaterThanOrEqual',
- value: 1
- }
- ]
- },
- {
- conditions: [
- {
- type: 'url',
- operator: 'matchDomain',
- value: 'example.com'
- },
- {
- type: 'url',
- operator: 'matchRegExp',
- value: 'example\\.com'
- }
- ]
- },
- {
- conditions: [
- {
- type: 'modifierKeys',
- operator: 'are',
- value: [
- 'ctrl',
- 'shift'
- ]
- },
- {
- type: 'modifierKeys',
- operator: 'areNot',
- value: [
- 'alt',
- 'shift'
- ]
- },
- {
- type: 'modifierKeys',
- operator: 'include',
- value: 'alt'
- },
- {
- type: 'modifierKeys',
- operator: 'notInclude',
- value: 'ctrl'
- }
- ]
- }
- ]
- }
- ],
- profileCurrent: 0,
- version: 2,
- global: {
- database: {
- prefixWildcardsSupported: false
- }
- }
- };
-}
-
-
-function createProfileOptionsUpdatedTestData1() {
- return {
- general: {
- enable: true,
- resultOutputMode: 'group',
- debugInfo: false,
- maxResults: 32,
- showAdvanced: false,
- popupDisplayMode: 'default',
- popupWidth: 400,
- popupHeight: 250,
- popupHorizontalOffset: 0,
- popupVerticalOffset: 10,
- popupHorizontalOffset2: 10,
- popupVerticalOffset2: 0,
- popupHorizontalTextPosition: 'below',
- popupVerticalTextPosition: 'before',
- popupScalingFactor: 1,
- popupScaleRelativeToPageZoom: false,
- popupScaleRelativeToVisualViewport: true,
- showGuide: true,
- compactTags: false,
- glossaryLayoutMode: 'default',
- mainDictionary: '',
- popupTheme: 'light',
- popupOuterTheme: 'light',
- customPopupCss: '',
- customPopupOuterCss: '',
- enableWanakana: true,
- showPitchAccentDownstepNotation: true,
- showPitchAccentPositionNotation: true,
- showPitchAccentGraph: false,
- showIframePopupsInRootFrame: false,
- useSecurePopupFrameUrl: true,
- usePopupShadowDom: true,
- usePopupWindow: false,
- popupCurrentIndicatorMode: 'triangle',
- popupActionBarVisibility: 'auto',
- popupActionBarLocation: 'top',
- frequencyDisplayMode: 'split-tags-grouped',
- termDisplayMode: 'ruby',
- sortFrequencyDictionary: null,
- sortFrequencyDictionaryOrder: 'descending'
- },
- audio: {
- enabled: true,
- sources: [
- {
- type: 'jpod101',
- url: '',
- voice: ''
- },
- {
- type: 'text-to-speech',
- url: '',
- voice: 'example-voice'
- },
- {
- type: 'custom',
- url: 'http://localhost/audio.mp3?term={term}&reading={reading}',
- voice: ''
- }
- ],
- volume: 100,
- autoPlay: false
- },
- scanning: {
- touchInputEnabled: true,
- selectText: true,
- alphanumeric: true,
- autoHideResults: false,
- delay: 20,
- length: 10,
- deepDomScan: false,
- popupNestingMaxDepth: 0,
- enablePopupSearch: false,
- enableOnPopupExpressions: false,
- enableOnSearchPage: true,
- enableSearchTags: false,
- layoutAwareScan: false,
- hideDelay: 0,
- pointerEventsEnabled: false,
- matchTypePrefix: false,
- hidePopupOnCursorExit: false,
- hidePopupOnCursorExitDelay: 0,
- normalizeCssZoom: true,
- preventMiddleMouse: {
- onWebPages: false,
- onPopupPages: false,
- onSearchPages: false,
- onSearchQuery: false
- },
- inputs: [
- {
- include: 'shift',
- exclude: 'mouse0',
- types: {
- mouse: true,
- touch: false,
- pen: false
- },
- options: {
- showAdvanced: false,
- searchTerms: true,
- searchKanji: true,
- scanOnTouchMove: true,
- scanOnTouchPress: true,
- scanOnTouchRelease: false,
- scanOnPenMove: true,
- scanOnPenHover: true,
- scanOnPenReleaseHover: false,
- scanOnPenPress: true,
- scanOnPenRelease: false,
- preventTouchScrolling: true,
- preventPenScrolling: true
- }
- },
- {
- include: 'mouse2',
- exclude: '',
- types: {
- mouse: true,
- touch: false,
- pen: false
- },
- options: {
- showAdvanced: false,
- searchTerms: true,
- searchKanji: true,
- scanOnTouchMove: true,
- scanOnTouchPress: true,
- scanOnTouchRelease: false,
- scanOnPenMove: true,
- scanOnPenHover: true,
- scanOnPenReleaseHover: false,
- scanOnPenPress: true,
- scanOnPenRelease: false,
- preventTouchScrolling: true,
- preventPenScrolling: true
- }
- },
- {
- include: '',
- exclude: '',
- types: {
- mouse: false,
- touch: true,
- pen: true
- },
- options: {
- showAdvanced: false,
- searchTerms: true,
- searchKanji: true,
- scanOnTouchMove: true,
- scanOnTouchPress: true,
- scanOnTouchRelease: false,
- scanOnPenMove: true,
- scanOnPenHover: true,
- scanOnPenReleaseHover: false,
- scanOnPenPress: true,
- scanOnPenRelease: false,
- preventTouchScrolling: true,
- preventPenScrolling: true
- }
- }
- ]
- },
- translation: {
- convertHalfWidthCharacters: 'false',
- convertNumericCharacters: 'false',
- convertAlphabeticCharacters: 'false',
- convertHiraganaToKatakana: 'false',
- convertKatakanaToHiragana: 'variant',
- collapseEmphaticSequences: 'false',
- textReplacements: {
- searchOriginal: true,
- groups: []
- }
- },
- dictionaries: [
- {
- name: 'Test Dictionary',
- priority: 0,
- enabled: true,
- allowSecondarySearches: false,
- definitionsCollapsible: 'not-collapsible'
- }
- ],
- parsing: {
- enableScanningParser: true,
- enableMecabParser: false,
- selectedParser: null,
- termSpacing: true,
- readingMode: 'hiragana'
- },
- anki: {
- enable: false,
- server: 'http://127.0.0.1:8765',
- tags: ['yomichan'],
- screenshot: {format: 'png', quality: 92},
- terms: {deck: '', model: '', fields: {}},
- kanji: {deck: '', model: '', fields: {}},
- duplicateScope: 'collection',
- duplicateScopeCheckAllModels: false,
- displayTags: 'never',
- checkForDuplicates: true,
- fieldTemplates: null,
- suspendNewCards: false,
- noteGuiMode: 'browse',
- apiKey: '',
- downloadTimeout: 0
- },
- sentenceParsing: {
- scanExtent: 200,
- terminationCharacterMode: 'custom',
- terminationCharacters: [
- {enabled: true, character1: '「', character2: '」', includeCharacterAtStart: false, includeCharacterAtEnd: false},
- {enabled: true, character1: '『', character2: '』', includeCharacterAtStart: false, includeCharacterAtEnd: false},
- {enabled: true, character1: '"', character2: '"', includeCharacterAtStart: false, includeCharacterAtEnd: false},
- {enabled: true, character1: '\'', character2: '\'', includeCharacterAtStart: false, includeCharacterAtEnd: false},
- {enabled: true, character1: '.', character2: null, includeCharacterAtStart: false, includeCharacterAtEnd: true},
- {enabled: true, character1: '!', character2: null, includeCharacterAtStart: false, includeCharacterAtEnd: true},
- {enabled: true, character1: '?', character2: null, includeCharacterAtStart: false, includeCharacterAtEnd: true},
- {enabled: true, character1: '.', character2: null, includeCharacterAtStart: false, includeCharacterAtEnd: true},
- {enabled: true, character1: '。', character2: null, includeCharacterAtStart: false, includeCharacterAtEnd: true},
- {enabled: true, character1: '!', character2: null, includeCharacterAtStart: false, includeCharacterAtEnd: true},
- {enabled: true, character1: '?', character2: null, includeCharacterAtStart: false, includeCharacterAtEnd: true},
- {enabled: true, character1: '…', character2: null, includeCharacterAtStart: false, includeCharacterAtEnd: true},
- {enabled: true, character1: '︒', character2: null, includeCharacterAtStart: false, includeCharacterAtEnd: true},
- {enabled: true, character1: '︕', character2: null, includeCharacterAtStart: false, includeCharacterAtEnd: true},
- {enabled: true, character1: '︖', character2: null, includeCharacterAtStart: false, includeCharacterAtEnd: true},
- {enabled: true, character1: '︙', character2: null, includeCharacterAtStart: false, includeCharacterAtEnd: true}
- ]
- },
- inputs: {
- hotkeys: [
- {action: 'close', argument: '', key: 'Escape', modifiers: [], scopes: ['popup'], enabled: true},
- {action: 'focusSearchBox', argument: '', key: 'Escape', modifiers: [], scopes: ['search'], enabled: true},
- {action: 'previousEntry', argument: '3', key: 'PageUp', modifiers: ['alt'], scopes: ['popup', 'search'], enabled: true},
- {action: 'nextEntry', argument: '3', key: 'PageDown', modifiers: ['alt'], scopes: ['popup', 'search'], enabled: true},
- {action: 'lastEntry', argument: '', key: 'End', modifiers: ['alt'], scopes: ['popup', 'search'], enabled: true},
- {action: 'firstEntry', argument: '', key: 'Home', modifiers: ['alt'], scopes: ['popup', 'search'], enabled: true},
- {action: 'previousEntry', argument: '1', key: 'ArrowUp', modifiers: ['alt'], scopes: ['popup', 'search'], enabled: true},
- {action: 'nextEntry', argument: '1', key: 'ArrowDown', modifiers: ['alt'], scopes: ['popup', 'search'], enabled: true},
- {action: 'historyBackward', argument: '', key: 'KeyB', modifiers: ['alt'], scopes: ['popup', 'search'], enabled: true},
- {action: 'historyForward', argument: '', key: 'KeyF', modifiers: ['alt'], scopes: ['popup', 'search'], enabled: true},
- {action: 'addNoteKanji', argument: '', key: 'KeyK', modifiers: ['alt'], scopes: ['popup', 'search'], enabled: true},
- {action: 'addNoteTermKanji', argument: '', key: 'KeyE', modifiers: ['alt'], scopes: ['popup', 'search'], enabled: true},
- {action: 'addNoteTermKana', argument: '', key: 'KeyR', modifiers: ['alt'], scopes: ['popup', 'search'], enabled: true},
- {action: 'playAudio', argument: '', key: 'KeyP', modifiers: ['alt'], scopes: ['popup', 'search'], enabled: true},
- {action: 'viewNote', argument: '', key: 'KeyV', modifiers: ['alt'], scopes: ['popup', 'search'], enabled: true},
- {action: 'copyHostSelection', argument: '', key: 'KeyC', modifiers: ['ctrl'], scopes: ['popup'], enabled: true}
- ]
- },
- popupWindow: {
- width: 400,
- height: 250,
- left: 0,
- top: 0,
- useLeft: false,
- useTop: false,
- windowType: 'popup',
- windowState: 'normal'
- },
- clipboard: {
- enableBackgroundMonitor: false,
- enableSearchPageMonitor: false,
- autoSearchContent: true,
- maximumSearchLength: 1000
- },
- accessibility: {
- forceGoogleDocsHtmlRendering: false
- }
- };
-}
-
-function createOptionsUpdatedTestData1() {
- return {
- profiles: [
- {
- name: 'Default',
- options: createProfileOptionsUpdatedTestData1(),
- conditionGroups: [
- {
- conditions: [
- {
- type: 'popupLevel',
- operator: 'equal',
- value: '1'
- },
- {
- type: 'popupLevel',
- operator: 'notEqual',
- value: '0'
- },
- {
- type: 'popupLevel',
- operator: 'lessThan',
- value: '3'
- },
- {
- type: 'popupLevel',
- operator: 'greaterThan',
- value: '0'
- },
- {
- type: 'popupLevel',
- operator: 'lessThanOrEqual',
- value: '2'
- },
- {
- type: 'popupLevel',
- operator: 'greaterThanOrEqual',
- value: '1'
- }
- ]
- },
- {
- conditions: [
- {
- type: 'url',
- operator: 'matchDomain',
- value: 'example.com'
- },
- {
- type: 'url',
- operator: 'matchRegExp',
- value: 'example\\.com'
- }
- ]
- },
- {
- conditions: [
- {
- type: 'modifierKeys',
- operator: 'are',
- value: 'ctrl, shift'
- },
- {
- type: 'modifierKeys',
- operator: 'areNot',
- value: 'alt, shift'
- },
- {
- type: 'modifierKeys',
- operator: 'include',
- value: 'alt'
- },
- {
- type: 'modifierKeys',
- operator: 'notInclude',
- value: 'ctrl'
- }
- ]
- }
- ]
- }
- ],
- profileCurrent: 0,
- version: 21,
- global: {
- database: {
- prefixWildcardsSupported: false
- }
- }
- };
-}
-
-
-async function testUpdate(extDir) {
- const vm = createVM(extDir);
- const [OptionsUtil] = vm.get(['OptionsUtil']);
- const optionsUtil = new OptionsUtil();
- await optionsUtil.prepare();
-
- const options = createOptionsTestData1();
- const optionsUpdated = clone(await optionsUtil.update(options));
- const optionsExpected = createOptionsUpdatedTestData1();
- assert.deepStrictEqual(optionsUpdated, optionsExpected);
-}
-
-async function testDefault(extDir) {
- const data = [
- (options) => options,
- (options) => {
- delete options.profiles[0].options.audio.autoPlay;
- },
- (options) => {
- options.profiles[0].options.audio.autoPlay = void 0;
- }
- ];
-
- const vm = createVM(extDir);
- const [OptionsUtil] = vm.get(['OptionsUtil']);
- const optionsUtil = new OptionsUtil();
- await optionsUtil.prepare();
-
- for (const modify of data) {
- const options = optionsUtil.getDefault();
-
- const optionsModified = clone(options);
- modify(optionsModified);
-
- const optionsUpdated = await optionsUtil.update(clone(optionsModified));
- assert.deepStrictEqual(clone(optionsUpdated), clone(options));
- }
-}
-
-async function testFieldTemplatesUpdate(extDir) {
- const vm = createVM(extDir);
- const [OptionsUtil, TemplatePatcher] = vm.get(['OptionsUtil', 'TemplatePatcher']);
- const optionsUtil = new OptionsUtil();
- await optionsUtil.prepare();
-
- const templatePatcher = new TemplatePatcher();
- const loadDataFile = (fileName) => {
- const content = fs.readFileSync(path.join(extDir, fileName), {encoding: 'utf8'});
- return templatePatcher.parsePatch(content).addition;
- };
- const updates = [
- {version: 2, changes: loadDataFile('data/templates/anki-field-templates-upgrade-v2.handlebars')},
- {version: 4, changes: loadDataFile('data/templates/anki-field-templates-upgrade-v4.handlebars')},
- {version: 6, changes: loadDataFile('data/templates/anki-field-templates-upgrade-v6.handlebars')},
- {version: 8, changes: loadDataFile('data/templates/anki-field-templates-upgrade-v8.handlebars')},
- {version: 10, changes: loadDataFile('data/templates/anki-field-templates-upgrade-v10.handlebars')},
- {version: 12, changes: loadDataFile('data/templates/anki-field-templates-upgrade-v12.handlebars')},
- {version: 13, changes: loadDataFile('data/templates/anki-field-templates-upgrade-v13.handlebars')},
- {version: 21, changes: loadDataFile('data/templates/anki-field-templates-upgrade-v21.handlebars')}
- ];
- const getUpdateAdditions = (startVersion, targetVersion) => {
- let value = '';
- for (const {version, changes} of updates) {
- if (version <= startVersion || version > targetVersion || changes.length === 0) { continue; }
- if (value.length > 0) { value += '\n'; }
- value += changes;
- }
- return value;
- };
-
- const data = [
- // Standard format
- {
- oldVersion: 0,
- newVersion: 12,
- old: `
-{{#*inline "character"}}
- {{~definition.character~}}
-{{/inline}}
-
-{{~> (lookup . "marker") ~}}`.trimStart(),
-
- expected: `
-{{#*inline "character"}}
- {{~definition.character~}}
-{{/inline}}
-
-<<<UPDATE-ADDITIONS>>>
-{{~> (lookup . "marker") ~}}`.trimStart()
- },
- // Non-standard marker format
- {
- oldVersion: 0,
- newVersion: 12,
- old: `
-{{#*inline "character"}}
- {{~definition.character~}}
-{{/inline}}
-
-{{~> (lookup . "marker2") ~}}`.trimStart(),
-
- expected: `
-{{#*inline "character"}}
- {{~definition.character~}}
-{{/inline}}
-
-{{~> (lookup . "marker2") ~}}
-<<<UPDATE-ADDITIONS>>>`.trimStart()
- },
- // Empty test
- {
- oldVersion: 0,
- newVersion: 12,
- old: `
-{{~> (lookup . "marker") ~}}`.trimStart(),
-
- expected: `
-<<<UPDATE-ADDITIONS>>>
-{{~> (lookup . "marker") ~}}`.trimStart()
- },
- // Definition tags update
- {
- oldVersion: 0,
- newVersion: 12,
- old: `
-{{#*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~}}
-{{/inline}}
-
-{{#*inline "glossary-single2"}}
- {{~#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~}}
-{{/inline}}
-
-{{#*inline "glossary"}}
- {{~> glossary-single definition brief=brief compactGlossaries=compactGlossaries~}}
- {{~> glossary-single definition brief=brief compactGlossaries=../compactGlossaries~}}
-{{/inline}}
-
-{{~> (lookup . "marker") ~}}
-`.trimStart(),
-
- expected: `
-{{#*inline "glossary-single"}}
- {{~#unless brief~}}
- {{~#scope~}}
- {{~#set "any" false}}{{/set~}}
- {{~#if definitionTags~}}{{#each definitionTags~}}
- {{~#if (op "||" (op "!" ../data.compactTags) (op "!" redundant))~}}
- {{~#if (get "any")}}, {{else}}<i>({{/if~}}
- {{name}}
- {{~#set "any" true}}{{/set~}}
- {{~/if~}}
- {{~/each~}}
- {{~#if (get "any")}})</i> {{/if~}}
- {{~/if~}}
- {{~/scope~}}
- {{~#if only~}}({{#each only}}{{{.}}}{{#unless @last}}, {{/unless}}{{/each}} only) {{/if~}}
- {{~/unless~}}
-{{/inline}}
-
-{{#*inline "glossary-single2"}}
- {{~#unless brief~}}
- {{~#scope~}}
- {{~#set "any" false}}{{/set~}}
- {{~#if definitionTags~}}{{#each definitionTags~}}
- {{~#if (op "||" (op "!" ../data.compactTags) (op "!" redundant))~}}
- {{~#if (get "any")}}, {{else}}<i>({{/if~}}
- {{name}}
- {{~#set "any" true}}{{/set~}}
- {{~/if~}}
- {{~/each~}}
- {{~#if (get "any")}})</i> {{/if~}}
- {{~/if~}}
- {{~/scope~}}
- {{~#if only~}}({{#each only}}{{{.}}}{{#unless @last}}, {{/unless}}{{/each}} only) {{/if~}}
- {{~/unless~}}
-{{/inline}}
-
-{{#*inline "glossary"}}
- {{~> glossary-single definition brief=brief compactGlossaries=compactGlossaries data=.~}}
- {{~> glossary-single definition brief=brief compactGlossaries=../compactGlossaries data=../.~}}
-{{/inline}}
-
-<<<UPDATE-ADDITIONS>>>
-{{~> (lookup . "marker") ~}}
-`.trimStart()
- },
- // glossary and glossary-brief update
- {
- oldVersion: 7,
- newVersion: 12,
- old: `
-{{#*inline "glossary-single"}}
- {{~#unless brief~}}
- {{~#scope~}}
- {{~#set "any" false}}{{/set~}}
- {{~#if definitionTags~}}{{#each definitionTags~}}
- {{~#if (op "||" (op "!" ../data.compactTags) (op "!" redundant))~}}
- {{~#if (get "any")}}, {{else}}<i>({{/if~}}
- {{name}}
- {{~#set "any" true}}{{/set~}}
- {{~/if~}}
- {{~/each~}}
- {{~#if (get "any")}})</i> {{/if~}}
- {{~/if~}}
- {{~/scope~}}
- {{~#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 "character"}}
- {{~definition.character~}}
-{{/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 data=../.}}</li>{{/each}}</ol>
- {{~else~}}
- {{~> glossary-single definition.definitions.[0] brief=brief compactGlossaries=compactGlossaries data=.~}}
- {{~/if~}}
- {{~else if merge~}}
- {{~#if definition.definitions.[1]~}}
- <ol>{{#each definition.definitions}}<li>{{> glossary-single brief=../brief compactGlossaries=../compactGlossaries data=../.}}</li>{{/each}}</ol>
- {{~else~}}
- {{~> glossary-single definition.definitions.[0] brief=brief compactGlossaries=compactGlossaries data=.~}}
- {{~/if~}}
- {{~else~}}
- {{~> glossary-single definition brief=brief compactGlossaries=compactGlossaries data=.~}}
- {{~/if~}}
- {{~/if~}}
- </div>
-{{/inline}}
-
-{{#*inline "glossary-brief"}}
- {{~> glossary brief=true ~}}
-{{/inline}}
-
-{{~> (lookup . "marker") ~}}`.trimStart(),
-
- expected: `
-{{#*inline "glossary-single"}}
- {{~#unless brief~}}
- {{~#scope~}}
- {{~#set "any" false}}{{/set~}}
- {{~#each definitionTags~}}
- {{~#if (op "||" (op "!" @root.compactTags) (op "!" redundant))~}}
- {{~#if (get "any")}}, {{else}}<i>({{/if~}}
- {{name}}
- {{~#set "any" true}}{{/set~}}
- {{~/if~}}
- {{~/each~}}
- {{~#unless noDictionaryTag~}}
- {{~#if (op "||" (op "!" @root.compactTags) (op "!==" dictionary (get "previousDictionary")))~}}
- {{~#if (get "any")}}, {{else}}<i>({{/if~}}
- {{dictionary}}
- {{~#set "any" true}}{{/set~}}
- {{~/if~}}
- {{~/unless~}}
- {{~#if (get "any")}})</i> {{/if~}}
- {{~/scope~}}
- {{~#if only~}}({{#each only}}{{.}}{{#unless @last}}, {{/unless}}{{/each}} only) {{/if~}}
- {{~/unless~}}
- {{~#if (op "<=" glossary.length 1)~}}
- {{#each glossary}}{{#multiLine}}{{.}}{{/multiLine}}{{/each}}
- {{~else if @root.compactGlossaries~}}
- {{#each glossary}}{{#multiLine}}{{.}}{{/multiLine}}{{#unless @last}} | {{/unless}}{{/each}}
- {{~else~}}
- <ul>{{#each glossary}}<li>{{#multiLine}}{{.}}{{/multiLine}}</li>{{/each}}</ul>
- {{~/if~}}
- {{~#set "previousDictionary" dictionary~}}{{~/set~}}
-{{/inline}}
-
-{{#*inline "character"}}
- {{~definition.character~}}
-{{/inline}}
-
-{{~#*inline "glossary"~}}
- <div style="text-align: left;">
- {{~#scope~}}
- {{~#if (op "===" definition.type "term")~}}
- {{~> glossary-single definition brief=brief noDictionaryTag=noDictionaryTag ~}}
- {{~else if (op "||" (op "===" definition.type "termGrouped") (op "===" definition.type "termMerged"))~}}
- {{~#if (op ">" definition.definitions.length 1)~}}
- <ol>{{~#each definition.definitions~}}<li>{{~> glossary-single . brief=../brief noDictionaryTag=../noDictionaryTag ~}}</li>{{~/each~}}</ol>
- {{~else~}}
- {{~#each definition.definitions~}}{{~> glossary-single . brief=../brief noDictionaryTag=../noDictionaryTag ~}}{{~/each~}}
- {{~/if~}}
- {{~else if (op "===" definition.type "kanji")~}}
- {{~#if (op ">" definition.glossary.length 1)~}}
- <ol>{{#each definition.glossary}}<li>{{.}}</li>{{/each}}</ol>
- {{~else~}}
- {{~#each definition.glossary~}}{{.}}{{~/each~}}
- {{~/if~}}
- {{~/if~}}
- {{~/scope~}}
- </div>
-{{~/inline~}}
-
-{{#*inline "glossary-no-dictionary"}}
- {{~> glossary noDictionaryTag=true ~}}
-{{/inline}}
-
-{{#*inline "glossary-brief"}}
- {{~> glossary brief=true ~}}
-{{/inline}}
-
-<<<UPDATE-ADDITIONS>>>
-{{~> (lookup . "marker") ~}}`.trimStart()
- },
- // formatGlossary update
- {
- oldVersion: 12,
- newVersion: 13,
- old: `
-{{#*inline "example"}}
- {{~#if (op "<=" glossary.length 1)~}}
- {{#each glossary}}{{#multiLine}}{{.}}{{/multiLine}}{{/each}}
- {{~else if @root.compactGlossaries~}}
- {{#each glossary}}{{#multiLine}}{{.}}{{/multiLine}}{{#unless @last}} | {{/unless}}{{/each}}
- {{~else~}}
- <ul>{{#each glossary}}<li>{{#multiLine}}{{.}}{{/multiLine}}</li>{{/each}}</ul>
- {{~/if~}}
-{{/inline}}
-
-{{~> (lookup . "marker") ~}}`.trimStart(),
-
- expected: `
-{{#*inline "example"}}
- {{~#if (op "<=" glossary.length 1)~}}
- {{#each glossary}}{{#formatGlossary ../dictionary}}{{{.}}}{{/formatGlossary}}{{/each}}
- {{~else if @root.compactGlossaries~}}
- {{#each glossary}}{{#formatGlossary ../dictionary}}{{{.}}}{{/formatGlossary}}{{#unless @last}} | {{/unless}}{{/each}}
- {{~else~}}
- <ul>{{#each glossary}}<li>{{#formatGlossary ../dictionary}}{{{.}}}{{/formatGlossary}}</li>{{/each}}</ul>
- {{~/if~}}
-{{/inline}}
-
-<<<UPDATE-ADDITIONS>>>
-{{~> (lookup . "marker") ~}}`.trimStart()
- },
- // hasMedia/getMedia update
- {
- oldVersion: 12,
- newVersion: 13,
- old: `
-{{#*inline "audio"}}
- {{~#if definition.audioFileName~}}
- [sound:{{definition.audioFileName}}]
- {{~/if~}}
-{{/inline}}
-
-{{#*inline "screenshot"}}
- <img src="{{definition.screenshotFileName}}" />
-{{/inline}}
-
-{{#*inline "clipboard-image"}}
- {{~#if definition.clipboardImageFileName~}}
- <img src="{{definition.clipboardImageFileName}}" />
- {{~/if~}}
-{{/inline}}
-
-{{#*inline "clipboard-text"}}
- {{~#if definition.clipboardText~}}{{definition.clipboardText}}{{~/if~}}
-{{/inline}}
-
-{{~> (lookup . "marker") ~}}`.trimStart(),
-
- expected: `
-{{#*inline "audio"}}
- {{~#if (hasMedia "audio")~}}
- [sound:{{#getMedia "audio"}}{{/getMedia}}]
- {{~/if~}}
-{{/inline}}
-
-{{#*inline "screenshot"}}
- {{~#if (hasMedia "screenshot")~}}
- <img src="{{#getMedia "screenshot"}}{{/getMedia}}" />
- {{~/if~}}
-{{/inline}}
-
-{{#*inline "clipboard-image"}}
- {{~#if (hasMedia "clipboardImage")~}}
- <img src="{{#getMedia "clipboardImage"}}{{/getMedia}}" />
- {{~/if~}}
-{{/inline}}
-
-{{#*inline "clipboard-text"}}
- {{~#if (hasMedia "clipboardText")}}{{#getMedia "clipboardText"}}{{/getMedia}}{{/if~}}
-{{/inline}}
-
-<<<UPDATE-ADDITIONS>>>
-{{~> (lookup . "marker") ~}}`.trimStart()
- },
- // hasMedia/getMedia update
- {
- oldVersion: 12,
- newVersion: 13,
- old: `
-{{! 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") ~}}`.trimStart(),
-
- expected: `
-{{! Pitch Accents }}
-{{#*inline "pitch-accent-item"}}
- {{~#pronunciation format=format reading=reading downstepPosition=position nasalPositions=nasalPositions devoicePositions=devoicePositions~}}{{~/pronunciation~}}
-{{/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='text'~}}
-{{/inline}}
-
-{{#*inline "pitch-accent-graphs"}}
- {{~> pitch-accent-list format='graph'~}}
-{{/inline}}
-
-{{#*inline "pitch-accent-positions"}}
- {{~> pitch-accent-list format='position'~}}
-{{/inline}}
-{{! End Pitch Accents }}
-
-<<<UPDATE-ADDITIONS>>>
-{{~> (lookup . "marker") ~}}`.trimStart()
- },
- // block helper update: furigana and furiganaPlain
- {
- oldVersion: 20,
- newVersion: 21,
- old: `
-{{#*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 "frequencies"}}
- {{~#if (op ">" definition.frequencies.length 0)~}}
- <ul style="text-align: left;">
- {{~#each definition.frequencies~}}
- <li>
- {{~#if (op "!==" ../definition.type "kanji")~}}
- {{~#if (op "||" (op ">" ../uniqueExpressions.length 1) (op ">" ../uniqueReadings.length 1))~}}(
- {{~#furigana expression reading~}}{{~/furigana~}}
- ) {{/if~}}
- {{~/if~}}
- {{~dictionary}}: {{frequency~}}
- </li>
- {{~/each~}}
- </ul>
- {{~/if~}}
-{{/inline}}
-
-{{~> (lookup . "marker") ~}}`.trimStart(),
-
- expected: `
-{{#*inline "furigana"}}
- {{~#if merge~}}
- {{~#each definition.expressions~}}
- <span class="expression-{{termFrequency}}">{{~furigana .~}}</span>
- {{~#unless @last}}、{{/unless~}}
- {{~/each~}}
- {{~else~}}
- {{furigana definition}}
- {{~/if~}}
-{{/inline}}
-
-{{#*inline "furigana-plain"}}
- {{~#if merge~}}
- {{~#each definition.expressions~}}
- <span class="expression-{{termFrequency}}">{{~furiganaPlain .~}}</span>
- {{~#unless @last}}、{{/unless~}}
- {{~/each~}}
- {{~else~}}
- {{furiganaPlain definition}}
- {{~/if~}}
-{{/inline}}
-
-{{#*inline "frequencies"}}
- {{~#if (op ">" definition.frequencies.length 0)~}}
- <ul style="text-align: left;">
- {{~#each definition.frequencies~}}
- <li>
- {{~#if (op "!==" ../definition.type "kanji")~}}
- {{~#if (op "||" (op ">" ../uniqueExpressions.length 1) (op ">" ../uniqueReadings.length 1))~}}(
- {{~furigana expression reading~}}
- ) {{/if~}}
- {{~/if~}}
- {{~dictionary}}: {{frequency~}}
- </li>
- {{~/each~}}
- </ul>
- {{~/if~}}
-{{/inline}}
-
-{{~> (lookup . "marker") ~}}`.trimStart()
- },
- // block helper update: formatGlossary
- {
- oldVersion: 20,
- newVersion: 21,
- old: `
-{{#*inline "glossary-single"}}
- {{~#unless brief~}}
- {{~#scope~}}
- {{~#set "any" false}}{{/set~}}
- {{~#each definitionTags~}}
- {{~#if (op "||" (op "!" @root.compactTags) (op "!" redundant))~}}
- {{~#if (get "any")}}, {{else}}<i>({{/if~}}
- {{name}}
- {{~#set "any" true}}{{/set~}}
- {{~/if~}}
- {{~/each~}}
- {{~#unless noDictionaryTag~}}
- {{~#if (op "||" (op "!" @root.compactTags) (op "!==" dictionary (get "previousDictionary")))~}}
- {{~#if (get "any")}}, {{else}}<i>({{/if~}}
- {{dictionary}}
- {{~#set "any" true}}{{/set~}}
- {{~/if~}}
- {{~/unless~}}
- {{~#if (get "any")}})</i> {{/if~}}
- {{~/scope~}}
- {{~#if only~}}({{#each only}}{{.}}{{#unless @last}}, {{/unless}}{{/each}} only) {{/if~}}
- {{~/unless~}}
- {{~#if (op "<=" glossary.length 1)~}}
- {{#each glossary}}{{#formatGlossary ../dictionary}}{{{.}}}{{/formatGlossary}}{{/each}}
- {{~else if @root.compactGlossaries~}}
- {{#each glossary}}{{#formatGlossary ../dictionary}}{{{.}}}{{/formatGlossary}}{{#unless @last}} | {{/unless}}{{/each}}
- {{~else~}}
- <ul>{{#each glossary}}<li>{{#formatGlossary ../dictionary}}{{{.}}}{{/formatGlossary}}</li>{{/each}}</ul>
- {{~/if~}}
- {{~#set "previousDictionary" dictionary~}}{{~/set~}}
-{{/inline}}
-
-{{~> (lookup . "marker") ~}}`.trimStart(),
-
- expected: `
-{{#*inline "glossary-single"}}
- {{~#unless brief~}}
- {{~#scope~}}
- {{~set "any" false~}}
- {{~#each definitionTags~}}
- {{~#if (op "||" (op "!" @root.compactTags) (op "!" redundant))~}}
- {{~#if (get "any")}}, {{else}}<i>({{/if~}}
- {{name}}
- {{~set "any" true~}}
- {{~/if~}}
- {{~/each~}}
- {{~#unless noDictionaryTag~}}
- {{~#if (op "||" (op "!" @root.compactTags) (op "!==" dictionary (get "previousDictionary")))~}}
- {{~#if (get "any")}}, {{else}}<i>({{/if~}}
- {{dictionary}}
- {{~set "any" true~}}
- {{~/if~}}
- {{~/unless~}}
- {{~#if (get "any")}})</i> {{/if~}}
- {{~/scope~}}
- {{~#if only~}}({{#each only}}{{.}}{{#unless @last}}, {{/unless}}{{/each}} only) {{/if~}}
- {{~/unless~}}
- {{~#if (op "<=" glossary.length 1)~}}
- {{#each glossary}}{{formatGlossary ../dictionary .}}{{/each}}
- {{~else if @root.compactGlossaries~}}
- {{#each glossary}}{{formatGlossary ../dictionary .}}{{#unless @last}} | {{/unless}}{{/each}}
- {{~else~}}
- <ul>{{#each glossary}}<li>{{formatGlossary ../dictionary .}}</li>{{/each}}</ul>
- {{~/if~}}
- {{~set "previousDictionary" dictionary~}}
-{{/inline}}
-
-{{~> (lookup . "marker") ~}}`.trimStart()
- },
- // block helper update: set and get
- {
- oldVersion: 20,
- newVersion: 21,
- old: `
-{{#*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 "stroke-count"}}
- {{~#scope~}}
- {{~#set "found" false}}{{/set~}}
- {{~#each definition.stats.misc~}}
- {{~#if (op "===" name "strokes")~}}
- {{~#set "found" true}}{{/set~}}
- Stroke count: {{value}}
- {{~/if~}}
- {{~/each~}}
- {{~#if (op "!" (get "found"))~}}
- Stroke count: Unknown
- {{~/if~}}
- {{~/scope~}}
-{{/inline}}
-
-{{#*inline "part-of-speech"}}
- {{~#scope~}}
- {{~#if (op "!==" definition.type "kanji")~}}
- {{~#set "first" true}}{{/set~}}
- {{~#each definition.expressions~}}
- {{~#each wordClasses~}}
- {{~#unless (get (concat "used_" .))~}}
- {{~> part-of-speech-pretty . ~}}
- {{~#unless (get "first")}}, {{/unless~}}
- {{~#set (concat "used_" .) true~}}{{~/set~}}
- {{~#set "first" false~}}{{~/set~}}
- {{~/unless~}}
- {{~/each~}}
- {{~/each~}}
- {{~#if (get "first")~}}Unknown{{~/if~}}
- {{~/if~}}
- {{~/scope~}}
-{{/inline}}
-
-{{~> (lookup . "marker") ~}}`.trimStart(),
-
- expected: `
-{{#*inline "pitch-accent-item-disambiguation"}}
- {{~#scope~}}
- {{~set "exclusive" (spread exclusiveExpressions exclusiveReadings)~}}
- {{~#if (op ">" (property (get "exclusive") "length") 0)~}}
- {{~set "separator" ""~}}
- <em>({{#each (get "exclusive")~}}
- {{~get "separator"~}}{{{.}}}
- {{~/each}} only) </em>
- {{~/if~}}
- {{~/scope~}}
-{{/inline}}
-
-{{#*inline "stroke-count"}}
- {{~#scope~}}
- {{~set "found" false~}}
- {{~#each definition.stats.misc~}}
- {{~#if (op "===" name "strokes")~}}
- {{~set "found" true~}}
- Stroke count: {{value}}
- {{~/if~}}
- {{~/each~}}
- {{~#if (op "!" (get "found"))~}}
- Stroke count: Unknown
- {{~/if~}}
- {{~/scope~}}
-{{/inline}}
-
-{{#*inline "part-of-speech"}}
- {{~#scope~}}
- {{~#if (op "!==" definition.type "kanji")~}}
- {{~set "first" true~}}
- {{~#each definition.expressions~}}
- {{~#each wordClasses~}}
- {{~#unless (get (concat "used_" .))~}}
- {{~> part-of-speech-pretty . ~}}
- {{~#unless (get "first")}}, {{/unless~}}
- {{~set (concat "used_" .) true~}}
- {{~set "first" false~}}
- {{~/unless~}}
- {{~/each~}}
- {{~/each~}}
- {{~#if (get "first")~}}Unknown{{~/if~}}
- {{~/if~}}
- {{~/scope~}}
-{{/inline}}
-
-{{~> (lookup . "marker") ~}}`.trimStart()
- },
- // block helper update: hasMedia and getMedia
- {
- oldVersion: 20,
- newVersion: 21,
- old: `
-{{#*inline "audio"}}
- {{~#if (hasMedia "audio")~}}
- [sound:{{#getMedia "audio"}}{{/getMedia}}]
- {{~/if~}}
-{{/inline}}
-
-{{#*inline "screenshot"}}
- {{~#if (hasMedia "screenshot")~}}
- <img src="{{#getMedia "screenshot"}}{{/getMedia}}" />
- {{~/if~}}
-{{/inline}}
-
-{{#*inline "clipboard-image"}}
- {{~#if (hasMedia "clipboardImage")~}}
- <img src="{{#getMedia "clipboardImage"}}{{/getMedia}}" />
- {{~/if~}}
-{{/inline}}
-
-{{#*inline "clipboard-text"}}
- {{~#if (hasMedia "clipboardText")}}{{#getMedia "clipboardText"}}{{/getMedia}}{{/if~}}
-{{/inline}}
-
-{{#*inline "selection-text"}}
- {{~#if (hasMedia "selectionText")}}{{#getMedia "selectionText"}}{{/getMedia}}{{/if~}}
-{{/inline}}
-
-{{#*inline "sentence-furigana"}}
- {{~#if definition.cloze~}}
- {{~#if (hasMedia "textFurigana" definition.cloze.sentence)~}}
- {{#getMedia "textFurigana" definition.cloze.sentence escape=false}}{{/getMedia}}
- {{~else~}}
- {{definition.cloze.sentence}}
- {{~/if~}}
- {{~/if~}}
-{{/inline}}
-
-{{~> (lookup . "marker") ~}}`.trimStart(),
-
- expected: `
-{{#*inline "audio"}}
- {{~#if (hasMedia "audio")~}}
- [sound:{{getMedia "audio"}}]
- {{~/if~}}
-{{/inline}}
-
-{{#*inline "screenshot"}}
- {{~#if (hasMedia "screenshot")~}}
- <img src="{{getMedia "screenshot"}}" />
- {{~/if~}}
-{{/inline}}
-
-{{#*inline "clipboard-image"}}
- {{~#if (hasMedia "clipboardImage")~}}
- <img src="{{getMedia "clipboardImage"}}" />
- {{~/if~}}
-{{/inline}}
-
-{{#*inline "clipboard-text"}}
- {{~#if (hasMedia "clipboardText")}}{{getMedia "clipboardText"}}{{/if~}}
-{{/inline}}
-
-{{#*inline "selection-text"}}
- {{~#if (hasMedia "selectionText")}}{{getMedia "selectionText"}}{{/if~}}
-{{/inline}}
-
-{{#*inline "sentence-furigana"}}
- {{~#if definition.cloze~}}
- {{~#if (hasMedia "textFurigana" definition.cloze.sentence)~}}
- {{getMedia "textFurigana" definition.cloze.sentence escape=false}}
- {{~else~}}
- {{definition.cloze.sentence}}
- {{~/if~}}
- {{~/if~}}
-{{/inline}}
-
-{{~> (lookup . "marker") ~}}`.trimStart()
- },
- // block helper update: pronunciation
- {
- oldVersion: 20,
- newVersion: 21,
- old: `
-{{#*inline "pitch-accent-item"}}
- {{~#pronunciation format=format reading=reading downstepPosition=position nasalPositions=nasalPositions devoicePositions=devoicePositions~}}{{~/pronunciation~}}
-{{/inline}}
-
-{{~> (lookup . "marker") ~}}`.trimStart(),
-
- expected: `
-{{#*inline "pitch-accent-item"}}
- {{~pronunciation format=format reading=reading downstepPosition=position nasalPositions=nasalPositions devoicePositions=devoicePositions~}}
-{{/inline}}
-
-{{~> (lookup . "marker") ~}}`.trimStart()
- }
- ];
-
- const updatesPattern = /<<<UPDATE-ADDITIONS>>>/g;
- for (const {old, expected, oldVersion, newVersion} of data) {
- const options = createOptionsTestData1();
- options.profiles[0].options.anki.fieldTemplates = old;
- options.version = oldVersion;
-
- const expected2 = expected.replace(updatesPattern, getUpdateAdditions(oldVersion, newVersion));
-
- const optionsUpdated = clone(await optionsUtil.update(options, newVersion));
- const fieldTemplatesActual = optionsUpdated.profiles[0].options.anki.fieldTemplates;
- assert.deepStrictEqual(fieldTemplatesActual, expected2);
- }
-}
-
-
-async function main() {
- const extDir = path.join(__dirname, '..', 'ext');
- await testUpdate(extDir);
- await testDefault(extDir);
- await testFieldTemplatesUpdate(extDir);
-}
-
-
-if (require.main === module) { testMain(main); }