@@ -7,7 +7,8 @@ import { summary } from 'itertools-ts/es';
7
7
import type { TFile } from 'obsidian' ;
8
8
import { Component , editorLivePreviewField } from 'obsidian' ;
9
9
import type { InlineFieldType } from 'packages/core/src/config/APIConfigs' ;
10
- import { Cm6_Util , MB_WidgetType } from 'packages/obsidian/src/cm6/Cm6_Util' ;
10
+ import type { MB_WidgetSpec } from 'packages/obsidian/src/cm6/Cm6_Util' ;
11
+ import { Cm6_Util , MB_WidgetType } from 'packages/obsidian/src/cm6/Cm6_Util' ;
11
12
import type MetaBindPlugin from 'packages/obsidian/src/main' ;
12
13
13
14
// eslint-disable-next-line @typescript-eslint/no-explicit-any
@@ -68,6 +69,7 @@ export function createMarkdownRenderChildWidgetEditorPlugin(plugin: MetaBindPlug
68
69
*/
69
70
updateWidgets ( view : EditorView ) : void {
70
71
// remove all decorations that are not visible and call unload manually
72
+ // this is needed because otherwise some decorations are not unloaded correctly
71
73
this . decorations = this . decorations . update ( {
72
74
filter : ( fromA , toA , decoration ) => {
73
75
const inVisibleRange = summary . anyMatch ( view . visibleRanges , range =>
@@ -76,11 +78,12 @@ export function createMarkdownRenderChildWidgetEditorPlugin(plugin: MetaBindPlug
76
78
77
79
if ( inVisibleRange ) {
78
80
return true ;
79
- }
81
+ } else {
82
+ const spec = decoration . spec as MB_WidgetSpec ;
80
83
81
- // eslint-disable-next-line @typescript-eslint/no-unsafe-call, @typescript-eslint/no-unsafe-member-access
82
- decoration . spec . mb_unload ?. ( ) ;
83
- return false ;
84
+ spec . mb_unload ?. ( ) ;
85
+ return false ;
86
+ }
84
87
} ,
85
88
} ) ;
86
89
@@ -135,17 +138,13 @@ export function createMarkdownRenderChildWidgetEditorPlugin(plugin: MetaBindPlug
135
138
filterFrom : from ,
136
139
filterTo : to ,
137
140
filter : ( _from , _to , decoration ) => {
138
- if ( widgetTypeToKeep ) {
139
- // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-assignment
140
- const widgetType = decoration . spec . mb_widgetType ;
141
+ const spec = decoration . spec as MB_WidgetSpec ;
141
142
142
- if ( widgetType === widgetTypeToKeep ) {
143
- return true ;
144
- }
143
+ if ( widgetTypeToKeep && spec . mb_widgetType === widgetTypeToKeep ) {
144
+ return true ;
145
145
}
146
146
147
- // eslint-disable-next-line @typescript-eslint/no-unsafe-call, @typescript-eslint/no-unsafe-member-access
148
- decoration . spec . mb_unload ?.( ) ;
147
+ spec . mb_unload ?.( ) ;
149
148
return false ;
150
149
} ,
151
150
} ) ;
@@ -171,11 +170,12 @@ export function createMarkdownRenderChildWidgetEditorPlugin(plugin: MetaBindPlug
171
170
const from = node . from - 1 ;
172
171
const to = node . to + 1 ;
173
172
174
- // check if the decoration already exists and only add it if it does not exist
173
+ // we check if there already is a decoration of the same type in the range
175
174
if ( Cm6_Util . existsDecorationOfTypeBetween ( this . decorations , widgetType , from , to ) ) {
176
175
return ;
177
176
}
178
177
178
+ // we can only render widgets if we have a current file
179
179
const currentFile = Cm6_Util . getCurrentFile ( view ) ;
180
180
if ( ! currentFile ) {
181
181
return ;
@@ -189,6 +189,7 @@ export function createMarkdownRenderChildWidgetEditorPlugin(plugin: MetaBindPlug
189
189
currentFile ,
190
190
) ;
191
191
const newDecorations = Array . isArray ( newDecoration ) ? newDecoration : [ newDecoration ] ;
192
+ // the render widget function might return an empty array if the widget is not supposed to be rendered
192
193
if ( newDecorations . length === 0 ) {
193
194
return ;
194
195
}
@@ -221,15 +222,22 @@ export function createMarkdownRenderChildWidgetEditorPlugin(plugin: MetaBindPlug
221
222
// node is inline code
222
223
if ( props . has ( 'inline-code' ) && ! props . has ( 'formatting' ) ) {
223
224
// check for selection or cursor overlap
224
- const selection = view . state . selection ;
225
- const hasSelectionOverlap = Cm6_Util . checkSelectionOverlap ( selection , node . from - 1 , node . to + 1 ) ;
225
+ const hasSelectionOverlap = Cm6_Util . checkSelectionOverlap (
226
+ view . state . selection ,
227
+ node . from - 1 ,
228
+ node . to + 1 ,
229
+ ) ;
226
230
const content = this . readNode ( view , node . from , node . to ) ;
227
231
const isLivePreview = this . isLivePreview ( view . state ) ;
232
+ // if we are in live preview mode, we only render the widget if there is no selection overlap
233
+ // otherwise the user has it's cursor within the bounds of the code for the field and we do syntax highlighting
234
+ // if we are not in live preview, so in source mode, we always do syntax highlighting
235
+ const shouldRenderField = ! hasSelectionOverlap && isLivePreview ;
228
236
229
237
return {
230
- shouldRender : ! hasSelectionOverlap && isLivePreview ,
231
- shouldHighlight :
232
- ( hasSelectionOverlap || ! isLivePreview ) && plugin . settings . enableSyntaxHighlighting ,
238
+ shouldRender : shouldRenderField ,
239
+ // we need to also check that the user has highlighting enabled in the settings
240
+ shouldHighlight : ! shouldRenderField && plugin . settings . enableSyntaxHighlighting ,
233
241
content : content . content ,
234
242
widgetType : content . widgetType ,
235
243
} ;
0 commit comments