1
+ import { escape } from 'lodash' ;
1
2
import { spriteIcon } from '~/lib/utils/common_utils' ;
2
3
import { differenceInMilliseconds } from '~/lib/utils/datetime_utility' ;
3
- import { s__ } from '~/locale' ;
4
+ import { s__ , sprintf } from '~/locale' ;
4
5
import { unrestrictedPages } from './constants' ;
5
6
6
- // Renders math using KaTeX in any element with the
7
- // `js-render-math` class
7
+ // Renders math using KaTeX in an element.
8
8
//
9
- // ### Example Markup
10
- //
11
- // <code class="js-render-math"></div>
9
+ // Typically for elements with the `js-render-math` class such as
10
+ // <code class="js-render-math"></code>
12
11
//
12
+ // See app/assets/javascripts/behaviors/markdown/render_gfm.js
13
13
14
14
const MAX_MATH_CHARS = 1000 ;
15
+ const MAX_MACRO_EXPANSIONS = 1000 ;
16
+ const MAX_USER_SPECIFIED_EMS = 20 ;
15
17
const MAX_RENDER_TIME_MS = 2000 ;
16
18
17
19
// Wait for the browser to reflow the layout. Reflowing SVG takes time.
@@ -74,13 +76,23 @@ class SafeMathRenderer {
74
76
const { parentNode } = el ;
75
77
parentNode . replaceChild ( wrapperElement , el ) ;
76
78
79
+ let message ;
80
+ if ( text . length > MAX_MATH_CHARS ) {
81
+ message = sprintf (
82
+ s__ (
83
+ 'math|This math block exceeds %{maxMathChars} characters, and may cause performance issues on this page.' ,
84
+ ) ,
85
+ { maxMathChars : MAX_MATH_CHARS } ,
86
+ ) ;
87
+ } else {
88
+ message = s__ ( 'math|Displaying this math block may cause performance issues on this page.' ) ;
89
+ }
90
+
77
91
const html = `
78
92
<div class="alert gl-alert gl-alert-warning alert-dismissible lazy-render-math-container js-lazy-render-math-container fade show" role="alert">
79
93
${ spriteIcon ( 'warning' , 'text-warning-600 s16 gl-alert-icon' ) }
80
94
<div class="display-flex gl-alert-content">
81
- <div>${ s__ (
82
- 'math|Displaying this math block may cause performance issues on this page' ,
83
- ) } </div>
95
+ <div>${ message } </div>
84
96
<div class="gl-alert-actions">
85
97
<button class="js-lazy-render-math btn gl-alert-action btn-confirm btn-md gl-button">Display anyway</button>
86
98
</div>
@@ -117,8 +129,10 @@ class SafeMathRenderer {
117
129
displayContainer . innerHTML = this . katex . renderToString ( text , {
118
130
displayMode : el . dataset . mathStyle === 'display' ,
119
131
throwOnError : true ,
120
- maxSize : 20 ,
121
- maxExpand : 20 ,
132
+ maxSize : MAX_USER_SPECIFIED_EMS ,
133
+ // See https://gitlab.com/gitlab-org/gitlab/-/merge_requests/111107 for
134
+ // reasoning behind this value
135
+ maxExpand : MAX_MACRO_EXPANSIONS ,
122
136
trust : ( context ) =>
123
137
// this config option restores the KaTeX pre-v0.11.0
124
138
// behavior of allowing certain commands and protocols
@@ -128,8 +142,17 @@ class SafeMathRenderer {
128
142
} ) ;
129
143
} catch ( e ) {
130
144
// Don't show a flash for now because it would override an existing flash message
131
- el . textContent = s__ ( 'math|There was an error rendering this math block' ) ;
132
- // el.style.color = '#d00';
145
+ if ( e . message . match ( / T o o m a n y e x p a n s i o n s / ) ) {
146
+ // this is controlled by the maxExpand parameter
147
+ el . textContent = s__ ( 'math|Too many expansions. Consider using multiple math blocks.' ) ;
148
+ } else {
149
+ // According to https://katex.org/docs/error.html, we need to ensure that
150
+ // the error message is escaped.
151
+ el . textContent = sprintf (
152
+ s__ ( 'math|There was an error rendering this math block. %{katexMessage}' ) ,
153
+ { katexMessage : escape ( e . message ) } ,
154
+ ) ;
155
+ }
133
156
el . className = 'katex-error' ;
134
157
}
135
158
0 commit comments