diff --git a/ext/js/data/anki-note-builder.js b/ext/js/data/anki-note-builder.js index f12846b1..dfd92493 100644 --- a/ext/js/data/anki-note-builder.js +++ b/ext/js/data/anki-note-builder.js @@ -51,15 +51,7 @@ class AnkiNoteBuilder { duplicateScopeCheckChildren = true; } - const data = { - definition, - mode, - context, - resultOutputMode, - glossaryLayoutMode, - compactTags, - injectedMedia - }; + const data = this._createData(definition, mode, context, resultOutputMode, glossaryLayoutMode, compactTags, injectedMedia); const formattedFieldValuePromises = []; for (const [, fieldValue] of fields) { const formattedFieldValuePromise = this._formatField(fieldValue, data, templates, errors); @@ -90,8 +82,34 @@ class AnkiNoteBuilder { }; } + async getRenderingData({ + definition, + mode, + context, + resultOutputMode='split', + glossaryLayoutMode='default', + compactTags=false, + injectedMedia=null, + marker=null + }) { + const data = this._createData(definition, mode, context, resultOutputMode, glossaryLayoutMode, compactTags, injectedMedia); + return await this._templateRenderer.getModifiedData({data, marker}, 'ankiNote'); + } + // Private + _createData(definition, mode, context, resultOutputMode, glossaryLayoutMode, compactTags, injectedMedia) { + return { + definition, + mode, + context, + resultOutputMode, + glossaryLayoutMode, + compactTags, + injectedMedia + }; + } + async _formatField(field, data, templates, errors=null) { return await this._stringReplaceAsync(field, this._markerPattern, async (g0, marker) => { try { diff --git a/ext/js/display/display.js b/ext/js/display/display.js index 7ded1e09..3f56e081 100644 --- a/ext/js/display/display.js +++ b/ext/js/display/display.js @@ -757,9 +757,7 @@ class Display extends EventDispatcher { _onDebugLogClick(e) { const link = e.currentTarget; const index = this._getClosestDefinitionIndex(link); - if (index < 0 || index >= this._definitions.length) { return; } - const definition = this._definitions[index]; - console.log(definition); + this._logDefinitionData(index); } _onDocumentElementMouseUp(e) { @@ -1375,6 +1373,7 @@ class Display extends EventDispatcher { } _replaceHistoryStateNoNavigate(state, content) { + console.trace('_replaceHistoryStateNoNavigate', state); const historyChangeIgnorePre = this._historyChangeIgnore; try { this._historyChangeIgnore = true; @@ -1866,4 +1865,32 @@ class Display extends EventDispatcher { const queryPostProcessor = this._queryPostProcessor; return typeof queryPostProcessor === 'function' ? queryPostProcessor(query) : query; } + + async _logDefinitionData(index) { + if (index < 0 || index >= this._definitions.length) { return; } + const definition = this._definitions[index]; + let ankiNoteData; + let ankiNoteDataException; + try { + const context = this._getNoteContext(); + const {general: {resultOutputMode, glossaryLayoutMode, compactTags}} = this._options; + ankiNoteData = await this._ankiNoteBuilder.getRenderingData({ + definition, + mode: 'test', + context, + resultOutputMode, + glossaryLayoutMode, + compactTags, + injectedMedia: null, + marker: 'test' + }); + } catch (e) { + ankiNoteDataException = e; + } + const result = {definition, ankiNoteData}; + if (typeof ankiNoteDataException !== 'undefined') { + result.ankiNoteDataException = ankiNoteDataException; + } + console.log(result); + } } diff --git a/ext/js/templates/template-renderer-frame-api.js b/ext/js/templates/template-renderer-frame-api.js index 4936a2af..6eebc199 100644 --- a/ext/js/templates/template-renderer-frame-api.js +++ b/ext/js/templates/template-renderer-frame-api.js @@ -19,7 +19,8 @@ class TemplateRendererFrameApi { constructor(templateRenderer) { this._templateRenderer = templateRenderer; this._windowMessageHandlers = new Map([ - ['render', {async: true, handler: this._onRender.bind(this)}] + ['render', {async: true, handler: this._onRender.bind(this)}], + ['getModifiedData', {async: true, handler: this._onGetModifiedData.bind(this)}] ]); } @@ -57,6 +58,11 @@ class TemplateRendererFrameApi { return await this._templateRenderer.render(template, data, type); } + async _onGetModifiedData({data, type}) { + const result = await this._templateRenderer.getModifiedData(data, type); + return this._clone(result); + } + _errorToJson(error) { try { if (error !== null && typeof error === 'object') { @@ -75,4 +81,8 @@ class TemplateRendererFrameApi { hasValue: true }; } + + _clone(value) { + return JSON.parse(JSON.stringify(value)); + } } diff --git a/ext/js/templates/template-renderer-proxy.js b/ext/js/templates/template-renderer-proxy.js index 6a49832b..aba45e6c 100644 --- a/ext/js/templates/template-renderer-proxy.js +++ b/ext/js/templates/template-renderer-proxy.js @@ -30,6 +30,11 @@ class TemplateRendererProxy { return await this._invoke('render', {template, data, type}); } + async getModifiedData(data, type) { + await this._prepareFrame(); + return await this._invoke('getModifiedData', {data, type}); + } + // Private async _prepareFrame() { diff --git a/ext/js/templates/template-renderer.js b/ext/js/templates/template-renderer.js index f72740d5..a7a4a842 100644 --- a/ext/js/templates/template-renderer.js +++ b/ext/js/templates/template-renderer.js @@ -29,8 +29,8 @@ class TemplateRenderer { this._dataTypes = new Map(); } - registerDataType(name, {modifier=null, modifierPost=null}) { - this._dataTypes.set(name, {modifier, modifierPost}); + registerDataType(name, {modifier=null}) { + this._dataTypes.set(name, {modifier}); } async render(template, data, type) { @@ -47,33 +47,39 @@ class TemplateRenderer { cache.set(template, instance); } - let modifier = null; - let modifierPost = null; - if (typeof type === 'string') { - const typeInfo = this._dataTypes.get(type); - if (typeof typeInfo !== 'undefined') { - ({modifier, modifierPost} = typeInfo); - } - } - try { - if (typeof modifier === 'function') { - data = modifier(data); - } - + data = this._getModifiedData(data, type); this._stateStack = [new Map()]; return instance(data).trim(); } finally { this._stateStack = null; - - if (typeof modifierPost === 'function') { - modifierPost(data); - } } } + async getModifiedData(data, type) { + return this._getModifiedData(data, type); + } + // Private + _getModifier(type) { + if (typeof type === 'string') { + const typeInfo = this._dataTypes.get(type); + if (typeof typeInfo !== 'undefined') { + return typeInfo.modifier; + } + } + return null; + } + + _getModifiedData(data, type) { + const modifier = this._getModifier(type); + if (typeof modifier === 'function') { + data = modifier(data); + } + return data; + } + _updateCacheSize(maxSize) { const cache = this._cache; let removeCount = cache.size - maxSize;