From f452c34f78b7e37e1829a95b82741dd3f22698fd Mon Sep 17 00:00:00 2001 From: wxiaoguang Date: Fri, 22 Oct 2021 10:39:27 +0800 Subject: [PATCH 1/2] Fix context popup error --- web_src/js/features/contextpopup.js | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/web_src/js/features/contextpopup.js b/web_src/js/features/contextpopup.js index b97f77275aeb7..589369954a67b 100644 --- a/web_src/js/features/contextpopup.js +++ b/web_src/js/features/contextpopup.js @@ -10,7 +10,15 @@ export default function initContextPopups() { if ($(this).hasClass('ref-external-issue')) { return; } - const [index, _issues, repo, owner] = $(this).attr('href').replace(/[#?].*$/, '').split('/').reverse(); + + // some links were not generated by us and may lack the href attribute + const href = $(this).attr('href'); + if (!href) return; + // again, a simple check to make sure the link href is likely generated by us + const fields = href.replace(/[#?].*$/, '').split('/'); + if (fields.length !== 4) return; + + const [owner, repo, _issues, index] = fields; const el = document.createElement('div'); el.className = 'ui custom popup hidden'; From 6c71d8b47ab8a574b0e733d35622c45ea2fa40c7 Mon Sep 17 00:00:00 2001 From: wxiaoguang Date: Fri, 22 Oct 2021 20:53:20 +0800 Subject: [PATCH 2/2] apply patch --- web_src/js/features/contextpopup.js | 11 +++-------- web_src/js/utils.js | 6 ++++++ web_src/js/utils.test.js | 20 +++++++++++++++++++- 3 files changed, 28 insertions(+), 9 deletions(-) diff --git a/web_src/js/features/contextpopup.js b/web_src/js/features/contextpopup.js index 589369954a67b..aa73aad2410dc 100644 --- a/web_src/js/features/contextpopup.js +++ b/web_src/js/features/contextpopup.js @@ -1,6 +1,7 @@ import Vue from 'vue'; import ContextPopup from '../components/ContextPopup.vue'; +import {parseIssueHref} from '../utils.js'; export default function initContextPopups() { const refIssues = $('.ref-issue'); @@ -11,14 +12,8 @@ export default function initContextPopups() { return; } - // some links were not generated by us and may lack the href attribute - const href = $(this).attr('href'); - if (!href) return; - // again, a simple check to make sure the link href is likely generated by us - const fields = href.replace(/[#?].*$/, '').split('/'); - if (fields.length !== 4) return; - - const [owner, repo, _issues, index] = fields; + const {owner, repo, index} = parseIssueHref($(this).attr('href')); + if (!owner) return; const el = document.createElement('div'); el.className = 'ui custom popup hidden'; diff --git a/web_src/js/utils.js b/web_src/js/utils.js index b555650bc535f..6310b2cb9984c 100644 --- a/web_src/js/utils.js +++ b/web_src/js/utils.js @@ -57,3 +57,9 @@ export function mqBinarySearch(feature, minValue, maxValue, step, unit) { } return mqBinarySearch(feature, minValue, mid - step, step, unit); // feature is < mid } + +export function parseIssueHref(href) { + const path = (href || '').replace(/[#?].*$/, ''); + const [_, owner, repo, type, index] = /([^/]+)\/([^/]+)\/(issues|pulls)\/([0-9]+)/.exec(path) || []; + return {owner, repo, type, index}; +} diff --git a/web_src/js/utils.test.js b/web_src/js/utils.test.js index 859046c87c976..3f6f921079249 100644 --- a/web_src/js/utils.test.js +++ b/web_src/js/utils.test.js @@ -1,5 +1,5 @@ import { - basename, extname, isObject, uniq, stripTags, joinPaths, + basename, extname, isObject, uniq, stripTags, joinPaths, parseIssueHref, } from './utils.js'; test('basename', () => { @@ -66,3 +66,21 @@ test('uniq', () => { test('stripTags', () => { expect(stripTags('test')).toEqual('test'); }); + +test('parseIssueHref', () => { + expect(parseIssueHref('/owner/repo/issues/1')).toEqual({owner: 'owner', repo: 'repo', type: 'issues', index: '1'}); + expect(parseIssueHref('/owner/repo/pulls/1?query')).toEqual({owner: 'owner', repo: 'repo', type: 'pulls', index: '1'}); + expect(parseIssueHref('/owner/repo/issues/1#hash')).toEqual({owner: 'owner', repo: 'repo', type: 'issues', index: '1'}); + expect(parseIssueHref('/sub/owner/repo/issues/1')).toEqual({owner: 'owner', repo: 'repo', type: 'issues', index: '1'}); + expect(parseIssueHref('/sub/sub2/owner/repo/pulls/1')).toEqual({owner: 'owner', repo: 'repo', type: 'pulls', index: '1'}); + expect(parseIssueHref('/sub/sub2/owner/repo/issues/1?query')).toEqual({owner: 'owner', repo: 'repo', type: 'issues', index: '1'}); + expect(parseIssueHref('/sub/sub2/owner/repo/issues/1#hash')).toEqual({owner: 'owner', repo: 'repo', type: 'issues', index: '1'}); + expect(parseIssueHref('https://example.com/owner/repo/issues/1')).toEqual({owner: 'owner', repo: 'repo', type: 'issues', index: '1'}); + expect(parseIssueHref('https://example.com/owner/repo/pulls/1?query')).toEqual({owner: 'owner', repo: 'repo', type: 'pulls', index: '1'}); + expect(parseIssueHref('https://example.com/owner/repo/issues/1#hash')).toEqual({owner: 'owner', repo: 'repo', type: 'issues', index: '1'}); + expect(parseIssueHref('https://example.com/sub/owner/repo/issues/1')).toEqual({owner: 'owner', repo: 'repo', type: 'issues', index: '1'}); + expect(parseIssueHref('https://example.com/sub/sub2/owner/repo/pulls/1')).toEqual({owner: 'owner', repo: 'repo', type: 'pulls', index: '1'}); + expect(parseIssueHref('https://example.com/sub/sub2/owner/repo/issues/1?query')).toEqual({owner: 'owner', repo: 'repo', type: 'issues', index: '1'}); + expect(parseIssueHref('https://example.com/sub/sub2/owner/repo/issues/1#hash')).toEqual({owner: 'owner', repo: 'repo', type: 'issues', index: '1'}); + expect(parseIssueHref('')).toEqual({owner: undefined, repo: undefined, type: undefined, index: undefined}); +});