diff options
| author | Darius Jahandarie <djahandarie@gmail.com> | 2023-10-22 23:34:48 +0000 | 
|---|---|---|
| committer | GitHub <noreply@github.com> | 2023-10-22 23:34:48 +0000 | 
| commit | c3148c6cf0522c5a3b3f3db6e495f401050c73f7 (patch) | |
| tree | 22d68f73f998241a8e0fa922727509349007e1da /ext/js | |
| parent | 7039438ce5087ba4236a81b197ee8c3bfd5164d2 (diff) | |
| parent | 757707539690b6aec45e9de8cd37fdfc907d8843 (diff) | |
Merge pull request #276 from praschke/block-helper-rewrite
Block helper rewrite
Diffstat (limited to 'ext/js')
| -rw-r--r-- | ext/js/background/backend.js | 20 | ||||
| -rw-r--r-- | ext/js/data/options-util.js | 35 | ||||
| -rw-r--r-- | ext/js/pages/welcome-main.js | 7 | ||||
| -rw-r--r-- | ext/js/templates/sandbox/anki-template-renderer.js | 54 | 
4 files changed, 67 insertions, 49 deletions
| diff --git a/ext/js/background/backend.js b/ext/js/background/backend.js index 308ae4d5..8e8e6945 100644 --- a/ext/js/background/backend.js +++ b/ext/js/background/backend.js @@ -2127,20 +2127,12 @@ class Backend {      }      async _openWelcomeGuidePageOnce() { -        if (isObject(chrome.storage) && isObject(chrome.storage.session)) { -            // Chrome -            chrome.storage.session.get(['openedWelcomePage']).then((result) => { -                if (!result.openedWelcomePage) { -                    this._openWelcomeGuidePage(); -                    chrome.storage.session.set({'openedWelcomePage': true}); -                } -            }); -        } else { -            // Firefox (storage.session is not supported yet) -            // NOTE: This means that the welcome page will repeatedly open in Firefox -            // until they support storage.session. -            this._openWelcomeGuidePage(); -        } +        chrome.storage.session.get(['openedWelcomePage']).then((result) => { +            if (!result.openedWelcomePage) { +                this._openWelcomeGuidePage(); +                chrome.storage.session.set({'openedWelcomePage': true}); +            } +        });      }      async _openWelcomeGuidePage() { diff --git a/ext/js/data/options-util.js b/ext/js/data/options-util.js index 2674701f..1f2ffb05 100644 --- a/ext/js/data/options-util.js +++ b/ext/js/data/options-util.js @@ -470,7 +470,8 @@ class OptionsUtil {              {async: false, update: this._updateVersion17.bind(this)},              {async: false, update: this._updateVersion18.bind(this)},              {async: false, update: this._updateVersion19.bind(this)}, -            {async: false, update: this._updateVersion20.bind(this)} +            {async: false, update: this._updateVersion20.bind(this)}, +            {async: true,  update: this._updateVersion21.bind(this)}          ];          if (typeof targetVersion === 'number' && targetVersion < result.length) {              result.splice(targetVersion); @@ -997,4 +998,36 @@ class OptionsUtil {          }          return options;      } + +    async _updateVersion21(options) { +        await this._applyAnkiFieldTemplatesPatch(options, '/data/templates/anki-field-templates-upgrade-v21.handlebars'); + +        let customTemplates = false; +        for (const {options: profileOptions} of options.profiles) { +            if (profileOptions.anki.fieldTemplates !== null) { +                customTemplates = true; +            } +        } + +        if (customTemplates && isObject(chrome.storage)) { +            chrome.storage.session.set({'needsCustomTemplatesWarning': true}); +            await this._createTab(chrome.runtime.getURL('/welcome.html')); +            chrome.storage.session.set({'openedWelcomePage': true}); +        } + +        return options; +    } + +    _createTab(url) { +        return new Promise((resolve, reject) => { +            chrome.tabs.create({url}, (tab) => { +                const e = chrome.runtime.lastError; +                if (e) { +                    reject(new Error(e.message)); +                } else { +                    resolve(tab); +                } +            }); +        }); +    }  } diff --git a/ext/js/pages/welcome-main.js b/ext/js/pages/welcome-main.js index 521ce2c2..8039dae5 100644 --- a/ext/js/pages/welcome-main.js +++ b/ext/js/pages/welcome-main.js @@ -58,6 +58,13 @@ async function setupGenericSettingsController(genericSettingController) {          setupEnvironmentInfo(); +        chrome.storage.session.get({'needsCustomTemplatesWarning': false}).then((result) => { +            if (result.needsCustomTemplatesWarning) { +                document.documentElement.dataset.warnCustomTemplates = 'true'; +                chrome.storage.session.remove(['needsCustomTemplatesWarning']); +            } +        }); +          const preparePromises = [];          const modalController = new ModalController(); diff --git a/ext/js/templates/sandbox/anki-template-renderer.js b/ext/js/templates/sandbox/anki-template-renderer.js index 789f0942..766c7798 100644 --- a/ext/js/templates/sandbox/anki-template-renderer.js +++ b/ext/js/templates/sandbox/anki-template-renderer.js @@ -68,9 +68,7 @@ class AnkiTemplateRenderer {              ['dumpObject',       this._dumpObject.bind(this)],              ['furigana',         this._furigana.bind(this)],              ['furiganaPlain',    this._furiganaPlain.bind(this)], -            ['kanjiLinks',       this._kanjiLinks.bind(this)],              ['multiLine',        this._multiLine.bind(this)], -            ['sanitizeCssClass', this._sanitizeCssClass.bind(this)],              ['regexReplace',     this._regexReplace.bind(this)],              ['regexMatch',       this._regexMatch.bind(this)],              ['mergeTags',        this._mergeTags.bind(this)], @@ -132,10 +130,14 @@ class AnkiTemplateRenderer {          return Handlebars.Utils.escapeExpression(text);      } +    _safeString(text) { +        return new Handlebars.SafeString(text); +    } +      // Template helpers -    _dumpObject(context, options) { -        const dump = JSON.stringify(options.fn(context), null, 4); +    _dumpObject(context, object) { +        const dump = JSON.stringify(object, null, 4);          return this._escape(dump);      } @@ -145,14 +147,16 @@ class AnkiTemplateRenderer {          let result = '';          for (const {text, reading: reading2} of segs) { -            if (reading2.length > 0) { -                result += `<ruby>${text}<rt>${reading2}</rt></ruby>`; +            const safeText = this._escape(text); +            const safeReading = this._escape(reading2); +            if (safeReading.length > 0) { +                result += `<ruby>${safeText}<rt>${safeReading}</rt></ruby>`;              } else { -                result += text; +                result += safeText;              }          } -        return result; +        return this._safeString(result);      }      _furiganaPlain(context, ...args) { @@ -173,29 +177,16 @@ class AnkiTemplateRenderer {      }      _getFuriganaExpressionAndReading(context, ...args) { -        const options = args[args.length - 1];          if (args.length >= 3) {              return {expression: args[0], reading: args[1]}; -        } else { -            const {expression, reading} = options.fn(context); +        } else if (args.length === 2) { +            const {expression, reading} = args[0];              return {expression, reading}; +        } else { +            return void 0;          }      } -    _kanjiLinks(context, options) { -        const jp = this._japaneseUtil; -        let result = ''; -        for (const c of options.fn(context)) { -            if (jp.isCodePointKanji(c.codePointAt(0))) { -                result += `<a href="#" class="kanji-link">${c}</a>`; -            } else { -                result += c; -            } -        } - -        return result; -    } -      _stringToMultiLineHtml(string) {          return string.split('\n').join('<br>');      } @@ -204,10 +195,6 @@ class AnkiTemplateRenderer {          return this._stringToMultiLineHtml(options.fn(context));      } -    _sanitizeCssClass(context, options) { -        return options.fn(context).replace(/[^_a-z0-9\u00a0-\uffff]/ig, '_'); -    } -      _regexReplace(context, ...args) {          // Usage:          // {{#regexReplace regex string [flags] [content]...}}content{{/regexReplace}} @@ -219,7 +206,7 @@ class AnkiTemplateRenderer {          const options = args[argCount];          let value = typeof options.fn === 'function' ? options.fn(context) : '';          if (argCount > 3) { -            value = `${args.slice(3).join('')}${value}`; +            value = `${args.slice(3, -1).join('')}${value}`;          }          if (argCount > 1) {              try { @@ -243,7 +230,7 @@ class AnkiTemplateRenderer {          const options = args[argCount];          let value = typeof options.fn === 'function' ? options.fn(context) : '';          if (argCount > 2) { -            value = `${args.slice(2).join('')}${value}`; +            value = `${args.slice(2, -1).join('')}${value}`;          }          if (argCount > 0) {              try { @@ -490,7 +477,7 @@ class AnkiTemplateRenderer {          this._normalizeHtml(container, styleApplier, datasetKeyIgnorePattern);          const result = container.innerHTML;          container.textContent = ''; -        return result; +        return this._safeString(result);      }      _normalizeHtml(root, styleApplier, datasetKeyIgnorePattern) { @@ -543,9 +530,8 @@ class AnkiTemplateRenderer {          return instance;      } -    _formatGlossary(context, dictionary, options) { +    _formatGlossary(context, dictionary, content, options) {          const data = options.data.root; -        const content = options.fn(context);          if (typeof content === 'string') { return this._stringToMultiLineHtml(this._escape(content)); }          if (!(typeof content === 'object' && content !== null)) { return ''; }          switch (content.type) { |