summaryrefslogtreecommitdiff
path: root/app/assets/javascripts/behaviors
diff options
context:
space:
mode:
Diffstat (limited to 'app/assets/javascripts/behaviors')
-rw-r--r--app/assets/javascripts/behaviors/copy_code.js2
-rw-r--r--app/assets/javascripts/behaviors/index.js2
-rw-r--r--app/assets/javascripts/behaviors/markdown/render_math.js52
-rw-r--r--app/assets/javascripts/behaviors/select2.js30
-rw-r--r--app/assets/javascripts/behaviors/shortcuts.js5
5 files changed, 43 insertions, 48 deletions
diff --git a/app/assets/javascripts/behaviors/copy_code.js b/app/assets/javascripts/behaviors/copy_code.js
index 0c81ae63f21..970864eef74 100644
--- a/app/assets/javascripts/behaviors/copy_code.js
+++ b/app/assets/javascripts/behaviors/copy_code.js
@@ -8,7 +8,7 @@ class CopyCodeButton extends HTMLElement {
this.for = uniqueId('code-');
const target = this.parentNode.querySelector('pre');
- if (!target) return;
+ if (!target || this.closest('.suggestions')) return;
target.setAttribute('id', this.for);
diff --git a/app/assets/javascripts/behaviors/index.js b/app/assets/javascripts/behaviors/index.js
index 220064e6673..1d36661ee63 100644
--- a/app/assets/javascripts/behaviors/index.js
+++ b/app/assets/javascripts/behaviors/index.js
@@ -7,7 +7,6 @@ import { loadStartupCSS } from './load_startup_css';
import initCopyAsGFM from './markdown/copy_as_gfm';
import './quick_submit';
import './requires_input';
-import initSelect2Dropdowns from './select2';
import initPageShortcuts from './shortcuts';
import './toggler_behavior';
import './preview_markdown';
@@ -21,7 +20,6 @@ initCopyToClipboard();
initPageShortcuts();
initCollapseSidebarOnWindowResize();
-initSelect2Dropdowns();
window.requestIdleCallback(
() => {
diff --git a/app/assets/javascripts/behaviors/markdown/render_math.js b/app/assets/javascripts/behaviors/markdown/render_math.js
index 7852a909160..b1bf6ebcb13 100644
--- a/app/assets/javascripts/behaviors/markdown/render_math.js
+++ b/app/assets/javascripts/behaviors/markdown/render_math.js
@@ -1,17 +1,19 @@
+import { escape } from 'lodash';
import { spriteIcon } from '~/lib/utils/common_utils';
import { differenceInMilliseconds } from '~/lib/utils/datetime_utility';
-import { s__ } from '~/locale';
+import { s__, sprintf } from '~/locale';
import { unrestrictedPages } from './constants';
-// Renders math using KaTeX in any element with the
-// `js-render-math` class
+// Renders math using KaTeX in an element.
//
-// ### Example Markup
-//
-// <code class="js-render-math"></div>
+// Typically for elements with the `js-render-math` class such as
+// <code class="js-render-math"></code>
//
+// See app/assets/javascripts/behaviors/markdown/render_gfm.js
const MAX_MATH_CHARS = 1000;
+const MAX_MACRO_EXPANSIONS = 1000;
+const MAX_USER_SPECIFIED_EMS = 20;
const MAX_RENDER_TIME_MS = 2000;
// Wait for the browser to reflow the layout. Reflowing SVG takes time.
@@ -69,17 +71,28 @@ class SafeMathRenderer {
codeElement.className = 'code';
codeElement.textContent = el.textContent;
+ codeElement.dataset.mathStyle = el.dataset.mathStyle;
const { parentNode } = el;
parentNode.replaceChild(wrapperElement, el);
+ let message;
+ if (text.length > MAX_MATH_CHARS) {
+ message = sprintf(
+ s__(
+ 'math|This math block exceeds %{maxMathChars} characters, and may cause performance issues on this page.',
+ ),
+ { maxMathChars: MAX_MATH_CHARS },
+ );
+ } else {
+ message = s__('math|Displaying this math block may cause performance issues on this page.');
+ }
+
const html = `
<div class="alert gl-alert gl-alert-warning alert-dismissible lazy-render-math-container js-lazy-render-math-container fade show" role="alert">
- ${spriteIcon('warning', 'text-warning-600 s16 gl-alert-icon')}
+ ${spriteIcon('warning', 'gl-text-orange-600 s16 gl-alert-icon')}
<div class="display-flex gl-alert-content">
- <div>${s__(
- 'math|Displaying this math block may cause performance issues on this page',
- )}</div>
+ <div>${message}</div>
<div class="gl-alert-actions">
<button class="js-lazy-render-math btn gl-alert-action btn-confirm btn-md gl-button">Display anyway</button>
</div>
@@ -116,8 +129,10 @@ class SafeMathRenderer {
displayContainer.innerHTML = this.katex.renderToString(text, {
displayMode: el.dataset.mathStyle === 'display',
throwOnError: true,
- maxSize: 20,
- maxExpand: 20,
+ maxSize: MAX_USER_SPECIFIED_EMS,
+ // See https://gitlab.com/gitlab-org/gitlab/-/merge_requests/111107 for
+ // reasoning behind this value
+ maxExpand: MAX_MACRO_EXPANSIONS,
trust: (context) =>
// this config option restores the KaTeX pre-v0.11.0
// behavior of allowing certain commands and protocols
@@ -127,8 +142,17 @@ class SafeMathRenderer {
});
} catch (e) {
// Don't show a flash for now because it would override an existing flash message
- el.textContent = s__('math|There was an error rendering this math block');
- // el.style.color = '#d00';
+ if (e.message.match(/Too many expansions/)) {
+ // this is controlled by the maxExpand parameter
+ el.textContent = s__('math|Too many expansions. Consider using multiple math blocks.');
+ } else {
+ // According to https://katex.org/docs/error.html, we need to ensure that
+ // the error message is escaped.
+ el.textContent = sprintf(
+ s__('math|There was an error rendering this math block. %{katexMessage}'),
+ { katexMessage: escape(e.message) },
+ );
+ }
el.className = 'katex-error';
}
diff --git a/app/assets/javascripts/behaviors/select2.js b/app/assets/javascripts/behaviors/select2.js
deleted file mode 100644
index 1f222d8c1f6..00000000000
--- a/app/assets/javascripts/behaviors/select2.js
+++ /dev/null
@@ -1,30 +0,0 @@
-import $ from 'jquery';
-import { loadCSSFile } from '../lib/utils/css_utils';
-
-export default () => {
- const $select2Elements = $('select.select2');
- if ($select2Elements.length) {
- import(/* webpackChunkName: 'select2' */ 'select2/select2')
- .then(() => {
- // eslint-disable-next-line promise/no-nesting
- loadCSSFile(gon.select2_css_path)
- .then(() => {
- $select2Elements.select2({
- width: 'resolve',
- minimumResultsForSearch: 10,
- dropdownAutoWidth: true,
- });
-
- // Close select2 on escape
- $('.js-select2').on('select2-close', () => {
- requestAnimationFrame(() => {
- $('.select2-container-active').removeClass('select2-container-active');
- $(':focus').blur();
- });
- });
- })
- .catch(() => {});
- })
- .catch(() => {});
- }
-};
diff --git a/app/assets/javascripts/behaviors/shortcuts.js b/app/assets/javascripts/behaviors/shortcuts.js
index 7352be0dbd5..12fdb2e2981 100644
--- a/app/assets/javascripts/behaviors/shortcuts.js
+++ b/app/assets/javascripts/behaviors/shortcuts.js
@@ -28,7 +28,10 @@ export default function initPageShortcuts() {
// TODO: replace this whitelist with something more automated/maintainable
if (page && !pagesWithCustomShortcuts.includes(page)) {
import(/* webpackChunkName: 'shortcutsBundle' */ './shortcuts/shortcuts')
- .then(({ default: Shortcuts }) => new Shortcuts())
+ .then(({ default: Shortcuts }) => {
+ const shortcuts = new Shortcuts();
+ window.toggleShortcutsHelp = shortcuts.onToggleHelp;
+ })
.catch(() => {});
}
return false;