1- import "katex/dist/katex.min.css" ;
2- import "markdown-it-texmath/css/texmath.css" ;
31import "./style.scss" ;
42
53import fsOperation from "fileSystem" ;
@@ -10,6 +8,7 @@ import openFile from "lib/openFile";
108import { highlightCodeBlock , initHighlighting } from "utils/codeHighlight" ;
119import {
1210 getMarkdownBaseUri ,
11+ hasMathContent ,
1312 isExternalLink ,
1413 isMarkdownPath ,
1514 renderMarkdown ,
@@ -19,6 +18,7 @@ import {
1918let previewController = null ;
2019let mermaidModulePromise = null ;
2120let mermaidThemeSignature = "" ;
21+ let mathStylesPromise = null ;
2222
2323function getThemeColor ( name , fallback ) {
2424 const value = getComputedStyle ( document . documentElement )
@@ -62,6 +62,18 @@ function getTargetElement(container, targetId) {
6262 ) ;
6363}
6464
65+ function getOffsetTopWithinContainer ( target , container ) {
66+ let top = 0 ;
67+ let element = target ;
68+
69+ while ( element && element !== container ) {
70+ top += element . offsetTop || 0 ;
71+ element = element . offsetParent ;
72+ }
73+
74+ return top ;
75+ }
76+
6577async function getMermaid ( ) {
6678 if ( ! mermaidModulePromise ) {
6779 mermaidModulePromise = import ( "mermaid" )
@@ -75,22 +87,43 @@ async function getMermaid() {
7587 return mermaidModulePromise ;
7688}
7789
90+ async function ensureMathStyles ( ) {
91+ if ( ! mathStylesPromise ) {
92+ mathStylesPromise = Promise . all ( [
93+ import ( "katex/dist/katex.min.css" ) ,
94+ import ( "markdown-it-texmath/css/texmath.css" ) ,
95+ ] ) . catch ( ( error ) => {
96+ mathStylesPromise = null ;
97+ throw error ;
98+ } ) ;
99+ }
100+
101+ return mathStylesPromise ;
102+ }
103+
78104function getMermaidThemeConfig ( ) {
79105 const backgroundColor = getThemeColor ( "--background-color" , "#1e1e1e" ) ;
80106 const panelColor = getThemeColor ( "--popup-background-color" , "#2a2f3a" ) ;
81107 const borderColor = getThemeColor ( "--border-color" , "#4a4f5a" ) ;
82108 const primaryTextColor = getThemeColor ( "--primary-text-color" , "#f5f5f5" ) ;
83109 const accentColor = getThemeColor ( "--link-text-color" , "#4ba3ff" ) ;
110+ const activeColor = getThemeColor ( "--active-color" , accentColor ) ;
84111
85112 return {
86113 startOnLoad : false ,
87114 securityLevel : "strict" ,
115+ htmlLabels : false ,
88116 theme : "base" ,
117+ flowchart : {
118+ htmlLabels : false ,
119+ } ,
89120 themeVariables : {
90121 darkMode : isDarkColor ( backgroundColor ) ,
91122 background : backgroundColor ,
92123 mainBkg : panelColor ,
93124 primaryColor : panelColor ,
125+ mainContrastColor : primaryTextColor ,
126+ textColor : primaryTextColor ,
94127 primaryTextColor,
95128 primaryBorderColor : borderColor ,
96129 lineColor : primaryTextColor ,
@@ -103,7 +136,29 @@ function getMermaidThemeConfig() {
103136 clusterBkg : panelColor ,
104137 clusterBorder : borderColor ,
105138 nodeBorder : borderColor ,
139+ nodeTextColor : primaryTextColor ,
140+ titleColor : primaryTextColor ,
141+ defaultLinkColor : activeColor ,
142+ actorTextColor : primaryTextColor ,
143+ labelTextColor : primaryTextColor ,
144+ loopTextColor : primaryTextColor ,
145+ noteTextColor : primaryTextColor ,
146+ sectionBkgColor : panelColor ,
147+ sectionBkgColor2 : backgroundColor ,
148+ sectionTitleColor : primaryTextColor ,
149+ sequenceNumberColor : primaryTextColor ,
150+ signalTextColor : primaryTextColor ,
151+ taskTextColor : primaryTextColor ,
152+ taskTextDarkColor : primaryTextColor ,
153+ taskTextOutsideColor : primaryTextColor ,
106154 edgeLabelBackground : backgroundColor ,
155+ pieTitleTextColor : primaryTextColor ,
156+ pieLegendTextColor : primaryTextColor ,
157+ pieSectionTextColor : primaryTextColor ,
158+ git0 : panelColor ,
159+ git1 : backgroundColor ,
160+ git2 : accentColor ,
161+ git3 : activeColor ,
107162 } ,
108163 } ;
109164}
@@ -186,15 +241,6 @@ async function resolveRenderedImages(container, file) {
186241 } ) ,
187242 ) ;
188243
189- container . querySelectorAll ( "a[href]" ) . forEach ( ( link ) => {
190- const href = link . getAttribute ( "href" ) ;
191- if ( ! href || href . startsWith ( "#" ) || isExternalLink ( href ) ) return ;
192- link . setAttribute (
193- "data-resolved-href" ,
194- resolveMarkdownTarget ( href , baseUri ) ,
195- ) ;
196- } ) ;
197-
198244 return objectUrls ;
199245}
200246
@@ -259,7 +305,11 @@ function createMarkdownPreview(file) {
259305
260306 const originalHref = link . getAttribute ( "href" ) || "" ;
261307 const resolvedHref =
262- link . getAttribute ( "data-resolved-href" ) || originalHref ;
308+ link . getAttribute ( "data-resolved-href" ) ||
309+ resolveMarkdownTarget (
310+ originalHref ,
311+ getMarkdownBaseUri ( previewState . file ) ,
312+ ) ;
263313 event . preventDefault ( ) ;
264314 event . stopPropagation ( ) ;
265315
@@ -302,11 +352,9 @@ function createMarkdownPreview(file) {
302352 const target = getTargetElement ( previewState . content , targetId ) ;
303353 if ( ! target ) return ;
304354
355+ const topOffset = 12 ;
305356 const top =
306- target . getBoundingClientRect ( ) . top -
307- previewState . content . getBoundingClientRect ( ) . top +
308- previewState . content . scrollTop -
309- 12 ;
357+ getOffsetTopWithinContainer ( target , previewState . content ) - topOffset ;
310358
311359 previewState . content . scrollTo ( {
312360 top : Math . max ( 0 , top ) ,
@@ -338,7 +386,10 @@ function createMarkdownPreview(file) {
338386 }
339387
340388 if ( highlighted && highlighted !== originalCode ) {
341- codeElement . innerHTML = highlighted ;
389+ codeElement . innerHTML = DOMPurify . sanitize ( highlighted , {
390+ ALLOWED_TAGS : [ "span" ] ,
391+ ALLOWED_ATTR : [ "class" ] ,
392+ } ) ;
342393 }
343394 } ) ,
344395 ) ;
@@ -404,6 +455,7 @@ function createMarkdownPreview(file) {
404455
405456 const sanitizedSvg = DOMPurify . sanitize ( svg , {
406457 USE_PROFILES : { svg : true , svgFilters : true } ,
458+ ADD_TAGS : [ "style" ] ,
407459 } ) ;
408460 block . innerHTML = sanitizedSvg ;
409461 bindFunctions ?. ( block ) ;
@@ -426,7 +478,13 @@ function createMarkdownPreview(file) {
426478 previewState . objectUrls = [ ] ;
427479
428480 const markdownText = previewState . file . session ?. doc ?. toString ?. ( ) || "" ;
429- const { html } = await renderMarkdown ( markdownText , previewState . file ) ;
481+ const pendingRenderTasks = [
482+ renderMarkdown ( markdownText , previewState . file ) ,
483+ ] ;
484+ if ( hasMathContent ( markdownText ) ) {
485+ pendingRenderTasks . push ( ensureMathStyles ( ) ) ;
486+ }
487+ const [ { html } ] = await Promise . all ( pendingRenderTasks ) ;
430488
431489 if ( previewState . disposed || version !== previewState . renderVersion ) {
432490 return ;
0 commit comments