aboutsummaryrefslogtreecommitdiffstats
path: root/web_src
diff options
context:
space:
mode:
authorwxiaoguang <wxiaoguang@gmail.com>2024-01-21 22:23:08 +0800
committerGitHub <noreply@github.com>2024-01-21 14:23:08 +0000
commit5d09023f1354f7a62f2ff68731e62e3e3645f4f2 (patch)
treee5da755b811fab5b1894ae93bcc2f2c277b93668 /web_src
parent0e6fd0d1c1e31d22707e6f06124d5bf76361eaab (diff)
downloadgitea-5d09023f1354f7a62f2ff68731e62e3e3645f4f2.tar.gz
gitea-5d09023f1354f7a62f2ff68731e62e3e3645f4f2.zip
Avoid duplicate JS error messages on UI (#28873)
Gitea treat JS errors seriously, so sometimes the JS errors caused by 3rdparty code (eg: browser extensions) would also be reported on Gitea UI: TypeError: WeakMap key undefined (caused by extension DarkReader's bug) #28861 To avoid fill the user's screen with a lot of error messages, this PR merges the same error messages into one, like this: ```js <div class="page-content"> <div class="... js-global-error" data-global-error-msg-compact="testmsg1" data-global-error-msg-count="2">test msg 1 (2)</div> <div class="... js-global-error" data-global-error-msg-compact="testmsg2" data-global-error-msg-count="1">test msg 2</div> </div> ```
Diffstat (limited to 'web_src')
-rw-r--r--web_src/js/bootstrap.js19
-rw-r--r--web_src/js/bootstrap.test.js12
-rw-r--r--web_src/js/test/setup.js2
3 files changed, 29 insertions, 4 deletions
diff --git a/web_src/js/bootstrap.js b/web_src/js/bootstrap.js
index 15e5b21204..f8d0c0cac0 100644
--- a/web_src/js/bootstrap.js
+++ b/web_src/js/bootstrap.js
@@ -8,10 +8,21 @@ __webpack_public_path__ = `${window.config?.assetUrlPrefix ?? '/assets'}/`;
export function showGlobalErrorMessage(msg) {
const pageContent = document.querySelector('.page-content');
if (!pageContent) return;
- const el = document.createElement('div');
- el.innerHTML = `<div class="ui container negative message center aligned js-global-error" style="white-space: pre-line;"></div>`;
- el.childNodes[0].textContent = msg;
- pageContent.prepend(el.childNodes[0]);
+
+ // compact the message to a data attribute to avoid too many duplicated messages
+ const msgCompact = msg.replace(/\W/g, '').trim();
+ let msgDiv = pageContent.querySelector(`.js-global-error[data-global-error-msg-compact="${msgCompact}"]`);
+ if (!msgDiv) {
+ const el = document.createElement('div');
+ el.innerHTML = `<div class="ui container negative message center aligned js-global-error" style="white-space: pre-line;"></div>`;
+ msgDiv = el.childNodes[0];
+ }
+ // merge duplicated messages into "the message (count)" format
+ const msgCount = Number(msgDiv.getAttribute(`data-global-error-msg-count`)) + 1;
+ msgDiv.setAttribute(`data-global-error-msg-compact`, msgCompact);
+ msgDiv.setAttribute(`data-global-error-msg-count`, msgCount.toString());
+ msgDiv.textContent = msg + (msgCount > 1 ? ` (${msgCount})` : '');
+ pageContent.prepend(msgDiv);
}
/**
diff --git a/web_src/js/bootstrap.test.js b/web_src/js/bootstrap.test.js
new file mode 100644
index 0000000000..a6b901b92c
--- /dev/null
+++ b/web_src/js/bootstrap.test.js
@@ -0,0 +1,12 @@
+import {showGlobalErrorMessage} from './bootstrap.js';
+
+test('showGlobalErrorMessage', () => {
+ document.body.innerHTML = '<div class="page-content"></div>';
+ showGlobalErrorMessage('test msg 1');
+ showGlobalErrorMessage('test msg 2');
+ showGlobalErrorMessage('test msg 1'); // duplicated
+
+ expect(document.body.innerHTML).toContain('>test msg 1 (2)<');
+ expect(document.body.innerHTML).toContain('>test msg 2<');
+ expect(document.querySelectorAll('.js-global-error').length).toEqual(2);
+});
diff --git a/web_src/js/test/setup.js b/web_src/js/test/setup.js
index 52355c7adc..6fb0f5dc8f 100644
--- a/web_src/js/test/setup.js
+++ b/web_src/js/test/setup.js
@@ -1,3 +1,5 @@
+window.__webpack_public_path__ = '';
+
window.config = {
csrfToken: 'test-csrf-token-123456',
pageData: {},