loading up the forgejo repo on tangled to test page performance
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

Enforce trailing comma in JS on multiline (#30002)

To keep blame info accurate and to avoid [changes like
this](https://github.com/go-gitea/gitea/pull/29977/files#diff-c3422631a14edbe1e508c4b22f0c718db318be08a6e889427802f9b6165d88d6R359),
it's good to always have a trailing comma, so let's enforce it in JS.

This rule is completely automatically fixable with `make lint-js-fix`
and that's what I did here.

(cherry picked from commit 3d751b6ec18e57698ce86b79866031d2c80c2071)

Conflicts:
web_src/js/components/DashboardRepoList.vue
trivial context conflict because of '3b7b899afa fix commit_status'

authored by

silverwind and committed by
Earl Warren
b96845ae 9c9f40f6

+117 -117
+1 -1
.eslintrc.yaml
··· 119 "@stylistic/js/arrow-spacing": [2, {before: true, after: true}] 120 "@stylistic/js/block-spacing": [0] 121 "@stylistic/js/brace-style": [2, 1tbs, {allowSingleLine: true}] 122 - "@stylistic/js/comma-dangle": [2, only-multiline] 123 "@stylistic/js/comma-spacing": [2, {before: false, after: true}] 124 "@stylistic/js/comma-style": [2, last] 125 "@stylistic/js/computed-property-spacing": [2, never]
··· 119 "@stylistic/js/arrow-spacing": [2, {before: true, after: true}] 120 "@stylistic/js/block-spacing": [0] 121 "@stylistic/js/brace-style": [2, 1tbs, {allowSingleLine: true}] 122 + "@stylistic/js/comma-dangle": [2, always-multiline] 123 "@stylistic/js/comma-spacing": [2, {before: false, after: true}] 124 "@stylistic/js/comma-style": [2, last] 125 "@stylistic/js/computed-property-spacing": [2, never]
+1 -1
playwright.config.js
··· 27 * Maximum time expect() should wait for the condition to be met. 28 * For example in `await expect(locator).toHaveText();` 29 */ 30 - timeout: 2000 31 }, 32 33 /* Fail the build on CI if you accidentally left test.only in the source code. */
··· 27 * Maximum time expect() should wait for the condition to be met. 28 * For example in `await expect(locator).toHaveText();` 29 */ 30 + timeout: 2000, 31 }, 32 33 /* Fail the build on CI if you accidentally left test.only in the source code. */
+1 -1
tools/generate-images.js
··· 20 'removeDimensions', 21 { 22 name: 'addAttributesToSVGElement', 23 - params: {attributes: [{width: size}, {height: size}]} 24 }, 25 ], 26 });
··· 20 'removeDimensions', 21 { 22 name: 'addAttributesToSVGElement', 23 + params: {attributes: [{width: size}, {height: size}]}, 24 }, 25 ], 26 });
+2 -2
tools/generate-svg.js
··· 39 attributes: [ 40 {'xmlns': 'http://www.w3.org/2000/svg'}, 41 {'width': '16'}, {'height': '16'}, {'aria-hidden': 'true'}, 42 - ] 43 - } 44 }, 45 ], 46 });
··· 39 attributes: [ 40 {'xmlns': 'http://www.w3.org/2000/svg'}, 41 {'width': '16'}, {'height': '16'}, {'aria-hidden': 'true'}, 42 + ], 43 + }, 44 }, 45 ], 46 });
+5 -5
web_src/js/components/ActionRunStatus.vue
··· 10 props: { 11 status: { 12 type: String, 13 - required: true 14 }, 15 size: { 16 type: Number, 17 - default: 16 18 }, 19 className: { 20 type: String, 21 - default: '' 22 }, 23 localeStatus: { 24 type: String, 25 - default: '' 26 - } 27 }, 28 }; 29 </script>
··· 10 props: { 11 status: { 12 type: String, 13 + required: true, 14 }, 15 size: { 16 type: Number, 17 + default: 16, 18 }, 19 className: { 20 type: String, 21 + default: '', 22 }, 23 localeStatus: { 24 type: String, 25 + default: '', 26 + }, 27 }, 28 }; 29 </script>
+2 -2
web_src/js/components/ActivityHeatmap.vue
··· 11 locale: { 12 type: Object, 13 default: () => {}, 14 - } 15 }, 16 data: () => ({ 17 colorRange: [ ··· 49 50 const newSearch = params.toString(); 51 window.location.search = newSearch.length ? `?${newSearch}` : ''; 52 - } 53 }, 54 }; 55 </script>
··· 11 locale: { 12 type: Object, 13 default: () => {}, 14 + }, 15 }, 16 data: () => ({ 17 colorRange: [ ··· 49 50 const newSearch = params.toString(); 51 window.location.search = newSearch.length ? `?${newSearch}` : ''; 52 + }, 53 }, 54 }; 55 </script>
+3 -3
web_src/js/components/ContextPopup.vue
··· 69 } 70 return {name: label.name, color: `#${label.color}`, textColor}; 71 }); 72 - } 73 }, 74 mounted() { 75 this.$refs.root.addEventListener('ce-load-context-popup', (e) => { ··· 97 } finally { 98 this.loading = false; 99 } 100 - } 101 - } 102 }; 103 </script> 104 <template>
··· 69 } 70 return {name: label.name, color: `#${label.color}`, textColor}; 71 }); 72 + }, 73 }, 74 mounted() { 75 this.$refs.root.addEventListener('ce-load-context-popup', (e) => { ··· 97 } finally { 98 this.loading = false; 99 } 100 + }, 101 + }, 102 }; 103 </script> 104 <template>
+2 -2
web_src/js/components/DashboardRepoList.vue
··· 252 return { 253 ...webSearchRepo.repository, 254 latest_commit_status: webSearchRepo.latest_commit_status, 255 - locale_latest_commit_status_state: webSearchRepo.locale_latest_commit_status 256 }; 257 }); 258 const count = response.headers.get('X-Total-Count'); ··· 324 if (this.activeIndex === -1 || this.activeIndex > this.repos.length - 1) { 325 this.activeIndex = 0; 326 } 327 - } 328 }, 329 }; 330
··· 252 return { 253 ...webSearchRepo.repository, 254 latest_commit_status: webSearchRepo.latest_commit_status, 255 + locale_latest_commit_status: webSearchRepo.locale_latest_commit_status, 256 }; 257 }); 258 const count = response.headers.get('X-Total-Count'); ··· 324 if (this.activeIndex === -1 || this.activeIndex > this.repos.length - 1) { 325 this.activeIndex = 0; 326 } 327 + }, 328 }, 329 }; 330
+3 -3
web_src/js/components/DiffCommitSelector.vue
··· 14 }, 15 commits: [], 16 hoverActivated: false, 17 - lastReviewCommitSha: null 18 }; 19 }, 20 computed: { ··· 29 }, 30 issueLink() { 31 return this.$el.parentNode.getAttribute('data-issuelink'); 32 - } 33 }, 34 mounted() { 35 document.body.addEventListener('click', this.onBodyClick); ··· 185 } 186 } 187 }, 188 - } 189 }; 190 </script> 191 <template>
··· 14 }, 15 commits: [], 16 hoverActivated: false, 17 + lastReviewCommitSha: null, 18 }; 19 }, 20 computed: { ··· 29 }, 30 issueLink() { 31 return this.$el.parentNode.getAttribute('data-issuelink'); 32 + }, 33 }, 34 mounted() { 35 document.body.addEventListener('click', this.onBodyClick); ··· 185 } 186 } 187 }, 188 + }, 189 }; 190 </script> 191 <template>
+1 -1
web_src/js/components/DiffFileList.vue
··· 31 }, 32 loadMoreData() { 33 loadMoreFiles(this.store.linkLoadMore); 34 - } 35 }, 36 }; 37 </script>
··· 31 }, 32 loadMoreData() { 33 loadMoreFiles(this.store.linkLoadMore); 34 + }, 35 }, 36 }; 37 </script>
+3 -3
web_src/js/components/DiffFileTree.vue
··· 30 let newParent = { 31 name: split, 32 children: [], 33 - isFile 34 }; 35 36 if (isFile === true) { ··· 40 if (parent) { 41 // check if the folder already exists 42 const existingFolder = parent.children.find( 43 - (x) => x.name === split 44 ); 45 if (existingFolder) { 46 newParent = existingFolder; ··· 74 // reduce the depth of our tree. 75 mergeChildIfOnlyOneDir(result); 76 return result; 77 - } 78 }, 79 mounted() { 80 // Default to true if unset
··· 30 let newParent = { 31 name: split, 32 children: [], 33 + isFile, 34 }; 35 36 if (isFile === true) { ··· 40 if (parent) { 41 // check if the folder already exists 42 const existingFolder = parent.children.find( 43 + (x) => x.name === split, 44 ); 45 if (existingFolder) { 46 newParent = existingFolder; ··· 74 // reduce the depth of our tree. 75 mergeChildIfOnlyOneDir(result); 76 return result; 77 + }, 78 }, 79 mounted() { 80 // Default to true if unset
+1 -1
web_src/js/components/DiffFileTreeItem.vue
··· 7 props: { 8 item: { 9 type: Object, 10 - required: true 11 }, 12 }, 13 data: () => ({
··· 7 props: { 8 item: { 9 type: Object, 10 + required: true, 11 }, 12 }, 13 data: () => ({
+1 -1
web_src/js/components/PullRequestMergeForm.vue
··· 43 for (const elem of document.querySelectorAll('[data-pull-merge-style]')) { 44 toggleElem(elem, elem.getAttribute('data-pull-merge-style') === val); 45 } 46 - } 47 }, 48 created() { 49 this.mergeStyleAllowedCount = this.mergeForm.mergeStyles.reduce((v, msd) => v + (msd.allowed ? 1 : 0), 0);
··· 43 for (const elem of document.querySelectorAll('[data-pull-merge-style]')) { 44 toggleElem(elem, elem.getAttribute('data-pull-merge-style') === val); 45 } 46 + }, 47 }, 48 created() { 49 this.mergeStyleAllowedCount = this.mergeForm.mergeStyles.reduce((v, msd) => v + (msd.allowed ? 1 : 0), 0);
+3 -3
web_src/js/components/RepoActionView.vue
··· 69 name: '', 70 link: '', 71 }, 72 - } 73 }, 74 currentJob: { 75 title: '', ··· 314 const logLine = this.$refs.steps.querySelector(selectedLogStep); 315 if (!logLine) return; 316 logLine.querySelector('.line-num').click(); 317 - } 318 }, 319 }; 320 ··· 357 skipped: el.getAttribute('data-locale-status-skipped'), 358 blocked: el.getAttribute('data-locale-status-blocked'), 359 }, 360 - } 361 }); 362 view.mount(el); 363 }
··· 69 name: '', 70 link: '', 71 }, 72 + }, 73 }, 74 currentJob: { 75 title: '', ··· 314 const logLine = this.$refs.steps.querySelector(selectedLogStep); 315 if (!logLine) return; 316 logLine.querySelector('.line-num').click(); 317 + }, 318 }, 319 }; 320 ··· 357 skipped: el.getAttribute('data-locale-status-skipped'), 358 blocked: el.getAttribute('data-locale-status-blocked'), 359 }, 360 + }, 361 }); 362 view.mount(el); 363 }
+1 -1
web_src/js/components/RepoActivityTopAuthors.vue
··· 47 this.colors.barColor = refStyle.backgroundColor; 48 this.colors.textColor = refStyle.color; 49 this.colors.textAltColor = refAltStyle.color; 50 - } 51 }; 52 53 export function initRepoActivityTopAuthorsChart() {
··· 47 this.colors.barColor = refStyle.backgroundColor; 48 this.colors.textColor = refStyle.color; 49 this.colors.textAltColor = refAltStyle.color; 50 + }, 51 }; 52 53 export function initRepoActivityTopAuthorsChart() {
+3 -3
web_src/js/components/RepoBranchTagSelector.vue
··· 36 }, 37 shouldCreateTag() { 38 return this.mode === 'tags'; 39 - } 40 }, 41 42 watch: { ··· 45 this.focusSearchField(); 46 this.fetchBranchesOrTags(); 47 } 48 - } 49 }, 50 51 beforeMount() { ··· 209 this.isLoading = false; 210 } 211 }, 212 - } 213 }; 214 215 export function initRepoBranchTagSelector(selector) {
··· 36 }, 37 shouldCreateTag() { 38 return this.mode === 'tags'; 39 + }, 40 }, 41 42 watch: { ··· 45 this.focusSearchField(); 46 this.fetchBranchesOrTags(); 47 } 48 + }, 49 }, 50 51 beforeMount() { ··· 209 this.isLoading = false; 210 } 211 }, 212 + }, 213 }; 214 215 export function initRepoBranchTagSelector(selector) {
+3 -3
web_src/js/components/RepoCodeFrequency.vue
··· 39 props: { 40 locale: { 41 type: Object, 42 - required: true 43 }, 44 }, 45 data: () => ({ ··· 128 }, 129 ticks: { 130 maxRotation: 0, 131 - maxTicksLimit: 12 132 }, 133 }, 134 y: { 135 ticks: { 136 - maxTicksLimit: 6 137 }, 138 }, 139 },
··· 39 props: { 40 locale: { 41 type: Object, 42 + required: true, 43 }, 44 }, 45 data: () => ({ ··· 128 }, 129 ticks: { 130 maxRotation: 0, 131 + maxTicksLimit: 12, 132 }, 133 }, 134 y: { 135 ticks: { 136 + maxTicksLimit: 6, 137 }, 138 }, 139 },
+4 -4
web_src/js/components/RepoContributors.vue
··· 34 chart.resetZoom(); 35 opts.instance.updateOtherCharts(args.event, true); 36 } 37 - } 38 }; 39 40 Chart.defaults.color = chartJsColors.text; ··· 82 this.xAxisMax = this.xAxisEnd; 83 this.type = val; 84 this.sortContributors(); 85 - } 86 }); 87 }, 88 methods: { ··· 175 // Normally, chartjs handles this automatically, but it will resize the graph when you 176 // zoom, pan etc. I think resizing the graph makes it harder to compare things visually. 177 const maxValue = Math.max( 178 - ...this.totalStats.weeks.map((o) => o[this.type]) 179 ); 180 const [coefficient, exp] = maxValue.toExponential().split('e').map(Number); 181 if (coefficient % 1 === 0) return maxValue; ··· 187 // for contributors' graph. If I let chartjs do this for me, it will choose different 188 // maxY value for each contributors' graph which again makes it harder to compare. 189 const maxValue = Math.max( 190 - ...this.sortedContributors.map((c) => c.max_contribution_type) 191 ); 192 const [coefficient, exp] = maxValue.toExponential().split('e').map(Number); 193 if (coefficient % 1 === 0) return maxValue;
··· 34 chart.resetZoom(); 35 opts.instance.updateOtherCharts(args.event, true); 36 } 37 + }, 38 }; 39 40 Chart.defaults.color = chartJsColors.text; ··· 82 this.xAxisMax = this.xAxisEnd; 83 this.type = val; 84 this.sortContributors(); 85 + }, 86 }); 87 }, 88 methods: { ··· 175 // Normally, chartjs handles this automatically, but it will resize the graph when you 176 // zoom, pan etc. I think resizing the graph makes it harder to compare things visually. 177 const maxValue = Math.max( 178 + ...this.totalStats.weeks.map((o) => o[this.type]), 179 ); 180 const [coefficient, exp] = maxValue.toExponential().split('e').map(Number); 181 if (coefficient % 1 === 0) return maxValue; ··· 187 // for contributors' graph. If I let chartjs do this for me, it will choose different 188 // maxY value for each contributors' graph which again makes it harder to compare. 189 const maxValue = Math.max( 190 + ...this.sortedContributors.map((c) => c.max_contribution_type), 191 ); 192 const [coefficient, exp] = maxValue.toExponential().split('e').map(Number); 193 if (coefficient % 1 === 0) return maxValue;
+3 -3
web_src/js/components/RepoRecentCommits.vue
··· 35 props: { 36 locale: { 37 type: Object, 38 - required: true 39 }, 40 }, 41 data: () => ({ ··· 105 }, 106 ticks: { 107 maxRotation: 0, 108 - maxTicksLimit: 52 109 }, 110 }, 111 y: { 112 ticks: { 113 - maxTicksLimit: 6 114 }, 115 }, 116 },
··· 35 props: { 36 locale: { 37 type: Object, 38 + required: true, 39 }, 40 }, 41 data: () => ({ ··· 105 }, 106 ticks: { 107 maxRotation: 0, 108 + maxTicksLimit: 52, 109 }, 110 }, 111 y: { 112 ticks: { 113 + maxTicksLimit: 6, 114 }, 115 }, 116 },
+2 -2
web_src/js/components/ScopedAccessTokenSelector.vue
··· 39 'repository', 40 'user'); 41 return categories; 42 - } 43 }, 44 45 mounted() { ··· 68 } 69 // no scopes selected, show validation error 70 showElem(warningEl); 71 - } 72 }, 73 }; 74
··· 39 'repository', 40 'user'); 41 return categories; 42 + }, 43 }, 44 45 mounted() { ··· 68 } 69 // no scopes selected, show validation error 70 showElem(warningEl); 71 + }, 72 }, 73 }; 74
+2 -2
web_src/js/features/captcha.js
··· 9 10 const params = { 11 sitekey: siteKey, 12 - theme: isDark ? 'dark' : 'light' 13 }; 14 15 switch (captchaEl.getAttribute('data-captcha-type')) { ··· 42 siteKey: { 43 instanceUrl: new URL(instanceURL), 44 key: siteKey, 45 - } 46 }); 47 break; 48 }
··· 9 10 const params = { 11 sitekey: siteKey, 12 + theme: isDark ? 'dark' : 'light', 13 }; 14 15 switch (captchaEl.getAttribute('data-captcha-type')) { ··· 42 siteKey: { 43 instanceUrl: new URL(instanceURL), 44 key: siteKey, 45 + }, 46 }); 47 break; 48 }
+1 -1
web_src/js/features/code-frequency.js
··· 11 loadingTitle: el.getAttribute('data-locale-loading-title'), 12 loadingTitleFailed: el.getAttribute('data-locale-loading-title-failed'), 13 loadingInfo: el.getAttribute('data-locale-loading-info'), 14 - } 15 }); 16 View.mount(el); 17 } catch (err) {
··· 11 loadingTitle: el.getAttribute('data-locale-loading-title'), 12 loadingTitleFailed: el.getAttribute('data-locale-loading-title-failed'), 13 loadingInfo: el.getAttribute('data-locale-loading-info'), 14 + }, 15 }); 16 View.mount(el); 17 } catch (err) {
+2 -2
web_src/js/features/codeeditor.js
··· 80 rules: [ 81 { 82 background: getColor('--color-code-bg'), 83 - } 84 ], 85 colors: { 86 'editor.background': getColor('--color-code-bg'), ··· 98 'input.foreground': getColor('--color-input-text'), 99 'scrollbar.shadow': getColor('--color-shadow'), 100 'progressBar.background': getColor('--color-primary'), 101 - } 102 }); 103 104 // Quick fix: https://github.com/microsoft/monaco-editor/issues/2962
··· 80 rules: [ 81 { 82 background: getColor('--color-code-bg'), 83 + }, 84 ], 85 colors: { 86 'editor.background': getColor('--color-code-bg'), ··· 98 'input.foreground': getColor('--color-input-text'), 99 'scrollbar.shadow': getColor('--color-shadow'), 100 'progressBar.background': getColor('--color-primary'), 101 + }, 102 }); 103 104 // Quick fix: https://github.com/microsoft/monaco-editor/issues/2962
+1 -1
web_src/js/features/common-global.js
··· 335 const data = await response.json(); 336 window.location.href = data.redirect; 337 } 338 - } 339 }).modal('show'); 340 } 341
··· 335 const data = await response.json(); 336 window.location.href = data.redirect; 337 } 338 + }, 339 }).modal('show'); 340 } 341
+1 -1
web_src/js/features/comp/EasyMDEToolbarActions.js
··· 139 }, 140 icon: svg('octicon-chevron-right'), 141 title: 'Add Inline Code', 142 - } 143 }; 144 145 for (const [key, value] of Object.entries(actions)) {
··· 139 }, 140 icon: svg('octicon-chevron-right'), 141 title: 'Add Inline Code', 142 + }, 143 }; 144 145 for (const [key, value] of Object.entries(actions)) {
+4 -4
web_src/js/features/comp/SearchUserBox.js
··· 22 $.each(response.data, (_i, item) => { 23 const resultItem = { 24 title: item.login, 25 - image: item.avatar_url 26 }; 27 if (item.full_name) { 28 resultItem.description = htmlEscape(item.full_name); ··· 37 if (allowEmailInput && items.length === 0 && looksLikeEmailAddressCheck.test(searchQuery)) { 38 const resultItem = { 39 title: searchQuery, 40 - description: allowEmailDescription 41 }; 42 items.push(resultItem); 43 } 44 45 return {results: items}; 46 - } 47 }, 48 searchFields: ['login', 'full_name'], 49 - showNoResults: false 50 }); 51 }
··· 22 $.each(response.data, (_i, item) => { 23 const resultItem = { 24 title: item.login, 25 + image: item.avatar_url, 26 }; 27 if (item.full_name) { 28 resultItem.description = htmlEscape(item.full_name); ··· 37 if (allowEmailInput && items.length === 0 && looksLikeEmailAddressCheck.test(searchQuery)) { 38 const resultItem = { 39 title: searchQuery, 40 + description: allowEmailDescription, 41 }; 42 items.push(resultItem); 43 } 44 45 return {results: items}; 46 + }, 47 }, 48 searchFields: ['login', 'full_name'], 49 + showNoResults: false, 50 }); 51 }
+1 -1
web_src/js/features/contextpopup.js
··· 37 interactiveBorder: 5, 38 onShow: () => { 39 el.firstChild.dispatchEvent(new CustomEvent('ce-load-context-popup', {detail: {owner, repo, index}})); 40 - } 41 }); 42 } 43 }
··· 37 interactiveBorder: 5, 38 onShow: () => { 39 el.firstChild.dispatchEvent(new CustomEvent('ce-load-context-popup', {detail: {owner, repo, index}})); 40 + }, 41 }); 42 } 43 }
+1 -1
web_src/js/features/contributors.js
··· 18 loadingTitle: el.getAttribute('data-locale-loading-title'), 19 loadingTitleFailed: el.getAttribute('data-locale-loading-title-failed'), 20 loadingInfo: el.getAttribute('data-locale-loading-info'), 21 - } 22 }); 23 View.mount(el); 24 } catch (err) {
··· 18 loadingTitle: el.getAttribute('data-locale-loading-title'), 19 loadingTitleFailed: el.getAttribute('data-locale-loading-title-failed'), 20 loadingInfo: el.getAttribute('data-locale-loading-info'), 21 + }, 22 }); 23 View.mount(el); 24 } catch (err) {
+1 -1
web_src/js/features/eventsource.sharedworker.js
··· 48 this.eventSource.addEventListener(eventType, (event) => { 49 this.notifyClients({ 50 type: eventType, 51 - data: event.data 52 }); 53 }); 54 }
··· 48 this.eventSource.addEventListener(eventType, (event) => { 49 this.notifyClients({ 50 type: eventType, 51 + data: event.data, 52 }); 53 }); 54 }
+15 -15
web_src/js/features/imagediff.js
··· 20 if (img.width > 1 && img.width < MaxSize && img.height > 1 && img.height < MaxSize) { 21 return { 22 width: img.width, 23 - height: img.height 24 }; 25 } 26 if (svg.hasAttribute('viewBox')) { 27 const viewBox = svg.viewBox.baseVal; 28 return { 29 width: DefaultSize, 30 - height: DefaultSize * viewBox.width / viewBox.height 31 }; 32 } 33 return { 34 width: DefaultSize, 35 - height: DefaultSize 36 }; 37 } 38 return null; ··· 42 function createContext(image1, image2) { 43 const size1 = { 44 width: image1 && image1.width || 0, 45 - height: image1 && image1.height || 0 46 }; 47 const size2 = { 48 width: image2 && image2.width || 0, 49 - height: image2 && image2.height || 0 50 }; 51 const max = { 52 width: Math.max(size2.width, size1.width), 53 - height: Math.max(size2.height, size1.height) 54 }; 55 56 return { ··· 63 Math.floor(max.width - size1.width) / 2, 64 Math.floor(max.height - size1.height) / 2, 65 Math.floor(max.width - size2.width) / 2, 66 - Math.floor(max.height - size2.height) / 2 67 - ] 68 }; 69 } 70 ··· 79 path: this.getAttribute('data-path-after'), 80 mime: this.getAttribute('data-mime-after'), 81 $images: $container.find('img.image-after'), // matches 3 <img> 82 - $boundsInfo: $container.find('.bounds-info-after') 83 }, { 84 path: this.getAttribute('data-path-before'), 85 mime: this.getAttribute('data-mime-before'), 86 $images: $container.find('img.image-before'), // matches 3 <img> 87 - $boundsInfo: $container.find('.bounds-info-before') 88 }]; 89 90 await Promise.all(imageInfos.map(async (info) => { ··· 222 223 sizes.image1.css({ 224 width: sizes.size1.width * factor, 225 - height: sizes.size1.height * factor 226 }); 227 sizes.image2.css({ 228 width: sizes.size2.width * factor, 229 - height: sizes.size2.height * factor 230 }); 231 sizes.image1.parent().css({ 232 margin: `${sizes.ratio[1] * factor}px ${sizes.ratio[0] * factor}px`, 233 width: sizes.size1.width * factor + 2, 234 - height: sizes.size1.height * factor + 2 235 }); 236 sizes.image2.parent().css({ 237 margin: `${sizes.ratio[3] * factor}px ${sizes.ratio[2] * factor}px`, 238 width: sizes.size2.width * factor + 2, 239 - height: sizes.size2.height * factor + 2 240 }); 241 242 // some inner elements are `position: absolute`, so the container's height must be large enough ··· 248 249 const $range = $container.find("input[type='range']"); 250 const onInput = () => sizes.image1.parent().css({ 251 - opacity: $range.val() / 100 252 }); 253 $range.on('input', onInput); 254 onInput();
··· 20 if (img.width > 1 && img.width < MaxSize && img.height > 1 && img.height < MaxSize) { 21 return { 22 width: img.width, 23 + height: img.height, 24 }; 25 } 26 if (svg.hasAttribute('viewBox')) { 27 const viewBox = svg.viewBox.baseVal; 28 return { 29 width: DefaultSize, 30 + height: DefaultSize * viewBox.width / viewBox.height, 31 }; 32 } 33 return { 34 width: DefaultSize, 35 + height: DefaultSize, 36 }; 37 } 38 return null; ··· 42 function createContext(image1, image2) { 43 const size1 = { 44 width: image1 && image1.width || 0, 45 + height: image1 && image1.height || 0, 46 }; 47 const size2 = { 48 width: image2 && image2.width || 0, 49 + height: image2 && image2.height || 0, 50 }; 51 const max = { 52 width: Math.max(size2.width, size1.width), 53 + height: Math.max(size2.height, size1.height), 54 }; 55 56 return { ··· 63 Math.floor(max.width - size1.width) / 2, 64 Math.floor(max.height - size1.height) / 2, 65 Math.floor(max.width - size2.width) / 2, 66 + Math.floor(max.height - size2.height) / 2, 67 + ], 68 }; 69 } 70 ··· 79 path: this.getAttribute('data-path-after'), 80 mime: this.getAttribute('data-mime-after'), 81 $images: $container.find('img.image-after'), // matches 3 <img> 82 + $boundsInfo: $container.find('.bounds-info-after'), 83 }, { 84 path: this.getAttribute('data-path-before'), 85 mime: this.getAttribute('data-mime-before'), 86 $images: $container.find('img.image-before'), // matches 3 <img> 87 + $boundsInfo: $container.find('.bounds-info-before'), 88 }]; 89 90 await Promise.all(imageInfos.map(async (info) => { ··· 222 223 sizes.image1.css({ 224 width: sizes.size1.width * factor, 225 + height: sizes.size1.height * factor, 226 }); 227 sizes.image2.css({ 228 width: sizes.size2.width * factor, 229 + height: sizes.size2.height * factor, 230 }); 231 sizes.image1.parent().css({ 232 margin: `${sizes.ratio[1] * factor}px ${sizes.ratio[0] * factor}px`, 233 width: sizes.size1.width * factor + 2, 234 + height: sizes.size1.height * factor + 2, 235 }); 236 sizes.image2.parent().css({ 237 margin: `${sizes.ratio[3] * factor}px ${sizes.ratio[2] * factor}px`, 238 width: sizes.size2.width * factor + 2, 239 + height: sizes.size2.height * factor + 2, 240 }); 241 242 // some inner elements are `position: absolute`, so the container's height must be large enough ··· 248 249 const $range = $container.find("input[type='range']"); 250 const onInput = () => sizes.image1.parent().css({ 251 + opacity: $range.val() / 100, 252 }); 253 $range.on('input', onInput); 254 onInput();
+1 -1
web_src/js/features/install.js
··· 19 const defaultDbHosts = { 20 mysql: '127.0.0.1:3306', 21 postgres: '127.0.0.1:5432', 22 - mssql: '127.0.0.1:1433' 23 }; 24 25 const dbHost = document.getElementById('db_host');
··· 19 const defaultDbHosts = { 20 mysql: '127.0.0.1:3306', 21 postgres: '127.0.0.1:5432', 22 + mssql: '127.0.0.1:1433', 23 }; 24 25 const dbHost = document.getElementById('db_host');
+3 -3
web_src/js/features/org-team.js
··· 26 $.each(response.data, (_i, item) => { 27 items.push({ 28 title: item.repository.full_name.split('/')[1], 29 - description: item.repository.full_name 30 }); 31 }); 32 33 return {results: items}; 34 - } 35 }, 36 searchFields: ['full_name'], 37 - showNoResults: false 38 }); 39 }
··· 26 $.each(response.data, (_i, item) => { 27 items.push({ 28 title: item.repository.full_name.split('/')[1], 29 + description: item.repository.full_name, 30 }); 31 }); 32 33 return {results: items}; 34 + }, 35 }, 36 searchFields: ['full_name'], 37 + showNoResults: false, 38 }); 39 }
+1 -1
web_src/js/features/recent-commits.js
··· 11 loadingTitle: el.getAttribute('data-locale-loading-title'), 12 loadingTitleFailed: el.getAttribute('data-locale-loading-title-failed'), 13 loadingInfo: el.getAttribute('data-locale-loading-info'), 14 - } 15 }); 16 View.mount(el); 17 } catch (err) {
··· 11 loadingTitle: el.getAttribute('data-locale-loading-title'), 12 loadingTitleFailed: el.getAttribute('data-locale-loading-title-failed'), 13 loadingInfo: el.getAttribute('data-locale-loading-info'), 14 + }, 15 }); 16 View.mount(el); 17 } catch (err) {
+1 -1
web_src/js/features/repo-code.js
··· 116 tippy.popper.addEventListener('click', () => { 117 tippy.hide(); 118 }, {once: true}); 119 - } 120 }); 121 } 122
··· 116 tippy.popper.addEventListener('click', () => { 117 tippy.hide(); 118 }, {once: true}); 119 + }, 120 }); 121 } 122
+6 -6
web_src/js/features/repo-home.js
··· 146 addedValue = addedValue.toLowerCase().trim(); 147 $($addedChoice).attr('data-value', addedValue); 148 $($addedChoice).attr('data-text', addedValue); 149 - } 150 }); 151 152 $.fn.form.settings.rules.validateTopic = function (_values, regExp) { ··· 168 { 169 type: 'validateTopic', 170 value: /^\s*[a-z0-9][-.a-z0-9]{0,35}\s*$/, 171 - prompt: topicPrompts.formatPrompt 172 }, 173 { 174 type: 'maxCount[25]', 175 - prompt: topicPrompts.countPrompt 176 - } 177 - ] 178 }, 179 - } 180 }); 181 }
··· 146 addedValue = addedValue.toLowerCase().trim(); 147 $($addedChoice).attr('data-value', addedValue); 148 $($addedChoice).attr('data-text', addedValue); 149 + }, 150 }); 151 152 $.fn.form.settings.rules.validateTopic = function (_values, regExp) { ··· 168 { 169 type: 'validateTopic', 170 value: /^\s*[a-z0-9][-.a-z0-9]{0,35}\s*$/, 171 + prompt: topicPrompts.formatPrompt, 172 }, 173 { 174 type: 'maxCount[25]', 175 + prompt: topicPrompts.countPrompt, 176 + }, 177 + ], 178 }, 179 + }, 180 }); 181 }
+1 -1
web_src/js/features/repo-issue-content.js
··· 60 }, 61 onHide() { 62 $(this).dropdown('clear', true); 63 - } 64 }); 65 $dialog.modal({ 66 async onShow() {
··· 60 }, 61 onHide() { 62 $(this).dropdown('clear', true); 63 + }, 64 }); 65 $dialog.modal({ 66 async onShow() {
+7 -7
web_src/js/features/repo-issue.js
··· 59 60 try { 61 const response = await POST($('#update-issue-deadline-form').attr('action'), { 62 - data: {due_date: realDeadline} 63 }); 64 65 if (response.ok) { ··· 268 $pullUpdateButton.find('.button-text').text($choice.text()); 269 $pullUpdateButton.data('do', $url); 270 } 271 - } 272 }); 273 } 274 ··· 316 $.each(response.data, (_r, repo) => { 317 filteredResponse.results.push({ 318 name: htmlEscape(repo.repository.full_name), 319 - value: repo.repository.full_name 320 }); 321 }); 322 return filteredResponse; ··· 327 const $form = $choice.closest('form'); 328 $form.attr('action', `${appSubUrl}/${_text}/issues/new`); 329 }, 330 - fullTextSearch: true 331 }); 332 } 333 ··· 443 } 444 window.scrollTo({ 445 top: $commentDiv.offset().top - offset, 446 - behavior: 'instant' 447 }); 448 } 449 } ··· 661 // Replace branch name to keep translation from HTML template 662 $selectionTextField.html($selectionTextField.html().replace( 663 `${baseName}:${branchNameOld}`, 664 - `${baseName}:${branchNameNew}` 665 )); 666 $selectionTextField.data('branch', branchNameNew); // update branch name in setting 667 }; ··· 695 const editor = await initComboMarkdownEditor($markdownEditor, { 696 onContentChanged: (editor) => { 697 $formField.val(editor.value()); 698 - } 699 }); 700 701 $formField.on('focus', async () => {
··· 59 60 try { 61 const response = await POST($('#update-issue-deadline-form').attr('action'), { 62 + data: {due_date: realDeadline}, 63 }); 64 65 if (response.ok) { ··· 268 $pullUpdateButton.find('.button-text').text($choice.text()); 269 $pullUpdateButton.data('do', $url); 270 } 271 + }, 272 }); 273 } 274 ··· 316 $.each(response.data, (_r, repo) => { 317 filteredResponse.results.push({ 318 name: htmlEscape(repo.repository.full_name), 319 + value: repo.repository.full_name, 320 }); 321 }); 322 return filteredResponse; ··· 327 const $form = $choice.closest('form'); 328 $form.attr('action', `${appSubUrl}/${_text}/issues/new`); 329 }, 330 + fullTextSearch: true, 331 }); 332 } 333 ··· 443 } 444 window.scrollTo({ 445 top: $commentDiv.offset().top - offset, 446 + behavior: 'instant', 447 }); 448 } 449 } ··· 661 // Replace branch name to keep translation from HTML template 662 $selectionTextField.html($selectionTextField.html().replace( 663 `${baseName}:${branchNameOld}`, 664 + `${baseName}:${branchNameNew}`, 665 )); 666 $selectionTextField.data('branch', branchNameNew); // update branch name in setting 667 }; ··· 695 const editor = await initComboMarkdownEditor($markdownEditor, { 696 onContentChanged: (editor) => { 697 $formField.val(editor.value()); 698 + }, 699 }); 700 701 $formField.on('focus', async () => {
+4 -4
web_src/js/features/repo-settings.js
··· 39 $text.text('(none)'); // prevent from misleading users when the access mode is undefined 40 } 41 }, 0); 42 - } 43 }); 44 }); 45 } ··· 56 $.each(response.data, (_i, item) => { 57 items.push({ 58 title: item.name, 59 - description: `${item.permission} access` // TODO: translate this string 60 }); 61 }); 62 63 return {results: items}; 64 - } 65 }, 66 searchFields: ['name', 'description'], 67 - showNoResults: false 68 }); 69 } 70
··· 39 $text.text('(none)'); // prevent from misleading users when the access mode is undefined 40 } 41 }, 0); 42 + }, 43 }); 44 }); 45 } ··· 56 $.each(response.data, (_i, item) => { 57 items.push({ 58 title: item.name, 59 + description: `${item.permission} access`, // TODO: translate this string 60 }); 61 }); 62 63 return {results: items}; 64 + }, 65 }, 66 searchFields: ['name', 'description'], 67 + showNoResults: false, 68 }); 69 } 70
+3 -3
web_src/js/features/repo-template.js
··· 29 const filteredResponse = {success: true, results: []}; 30 filteredResponse.results.push({ 31 name: '', 32 - value: '' 33 }); 34 // Parse the response from the api to work with our dropdown 35 $.each(response.data, (_r, repo) => { 36 filteredResponse.results.push({ 37 name: htmlEscape(repo.repository.full_name), 38 - value: repo.repository.id 39 }); 40 }); 41 return filteredResponse; ··· 43 cache: false, 44 }, 45 46 - fullTextSearch: true 47 }); 48 }; 49 $('#uid').on('change', changeOwner);
··· 29 const filteredResponse = {success: true, results: []}; 30 filteredResponse.results.push({ 31 name: '', 32 + value: '', 33 }); 34 // Parse the response from the api to work with our dropdown 35 $.each(response.data, (_r, repo) => { 36 filteredResponse.results.push({ 37 name: htmlEscape(repo.repository.full_name), 38 + value: repo.repository.id, 39 }); 40 }); 41 return filteredResponse; ··· 43 cache: false, 44 }, 45 46 + fullTextSearch: true, 47 }); 48 }; 49 $('#uid').on('change', changeOwner);
+1 -1
web_src/js/features/repo-wiki.js
··· 60 'gitea-code-inline', 'code', 'quote', '|', 'gitea-checkbox-empty', 'gitea-checkbox-checked', '|', 61 'unordered-list', 'ordered-list', '|', 62 'link', 'image', 'table', 'horizontal-rule', '|', 63 - 'preview', 'fullscreen', 'side-by-side', '|', 'gitea-switch-to-textarea' 64 ], 65 }, 66 });
··· 60 'gitea-code-inline', 'code', 'quote', '|', 'gitea-checkbox-empty', 'gitea-checkbox-checked', '|', 61 'unordered-list', 'ordered-list', '|', 62 'link', 'image', 'table', 'horizontal-rule', '|', 63 + 'preview', 'fullscreen', 'side-by-side', '|', 'gitea-switch-to-textarea', 64 ], 65 }, 66 });
+2 -2
web_src/js/features/tribute.js
··· 25 }, 26 menuItemTemplate: (item) => { 27 return `<div class="tribute-item">${emojiHTML(item.original)}<span>${htmlEscape(item.original)}</span></div>`; 28 - } 29 }); 30 } 31 ··· 41 ${item.original.fullname && item.original.fullname !== '' ? `<span class="fullname">${htmlEscape(item.original.fullname)}</span>` : ''} 42 </div> 43 `; 44 - } 45 }); 46 } 47
··· 25 }, 26 menuItemTemplate: (item) => { 27 return `<div class="tribute-item">${emojiHTML(item.original)}<span>${htmlEscape(item.original)}</span></div>`; 28 + }, 29 }); 30 } 31 ··· 41 ${item.original.fullname && item.original.fullname !== '' ? `<span class="fullname">${htmlEscape(item.original.fullname)}</span>` : ''} 42 </div> 43 `; 44 + }, 45 }); 46 } 47
+3 -3
web_src/js/features/user-auth-webauthn.js
··· 26 } 27 try { 28 const credential = await navigator.credentials.get({ 29 - publicKey: options.publicKey 30 }); 31 await verifyAssertion(credential); 32 } catch (err) { ··· 37 delete options.publicKey.extensions.appid; 38 try { 39 const credential = await navigator.credentials.get({ 40 - publicKey: options.publicKey 41 }); 42 await verifyAssertion(credential); 43 } catch (err) { ··· 185 186 try { 187 const credential = await navigator.credentials.create({ 188 - publicKey: options.publicKey 189 }); 190 await webauthnRegistered(credential); 191 } catch (err) {
··· 26 } 27 try { 28 const credential = await navigator.credentials.get({ 29 + publicKey: options.publicKey, 30 }); 31 await verifyAssertion(credential); 32 } catch (err) { ··· 37 delete options.publicKey.extensions.appid; 38 try { 39 const credential = await navigator.credentials.get({ 40 + publicKey: options.publicKey, 41 }); 42 await verifyAssertion(credential); 43 } catch (err) { ··· 185 186 try { 187 const credential = await navigator.credentials.create({ 188 + publicKey: options.publicKey, 189 }); 190 await webauthnRegistered(credential); 191 } catch (err) {
+1 -1
web_src/js/modules/tippy.js
··· 148 const observerConnect = (observer) => observer.observe(document, { 149 subtree: true, 150 childList: true, 151 - attributeFilter: ['data-tooltip-content', 'title'] 152 }); 153 const observer = new MutationObserver((mutationList, observer) => { 154 const pending = observer.takeRecords();
··· 148 const observerConnect = (observer) => observer.observe(document, { 149 subtree: true, 150 childList: true, 151 + attributeFilter: ['data-tooltip-content', 'title'], 152 }); 153 const observer = new MutationObserver((mutationList, observer) => { 154 const pending = observer.takeRecords();
+3 -3
web_src/js/standalone/swagger.js
··· 21 docExpansion: 'none', 22 defaultModelRendering: 'model', // don't show examples by default, because they may be incomplete 23 presets: [ 24 - SwaggerUI.presets.apis 25 ], 26 plugins: [ 27 - SwaggerUI.plugins.DownloadUrl 28 - ] 29 }); 30 31 window.ui = ui;
··· 21 docExpansion: 'none', 22 defaultModelRendering: 'model', // don't show examples by default, because they may be incomplete 23 presets: [ 24 + SwaggerUI.presets.apis, 25 ], 26 plugins: [ 27 + SwaggerUI.plugins.DownloadUrl, 28 + ], 29 }); 30 31 window.ui = ui;
+1 -1
web_src/js/svg.js
··· 189 name: {type: String, required: true}, 190 size: {type: Number, default: 16}, 191 className: {type: String, default: ''}, 192 - symbolId: {type: String} 193 }, 194 render() { 195 let {svgOuter, svgInnerHtml} = svgParseOuterInner(this.name);
··· 189 name: {type: String, required: true}, 190 size: {type: Number, default: 16}, 191 className: {type: String, default: ''}, 192 + symbolId: {type: String}, 193 }, 194 render() { 195 let {svgOuter, svgInnerHtml} = svgParseOuterInner(this.name);
+1 -1
web_src/js/utils/dom.js
··· 191 textarea.removeEventListener('mousemove', onUserResize); 192 textarea.removeEventListener('input', resizeToFit); 193 textarea.form?.removeEventListener('reset', onFormReset); 194 - } 195 }; 196 } 197
··· 191 textarea.removeEventListener('mousemove', onUserResize); 192 textarea.removeEventListener('input', resizeToFit); 193 textarea.form?.removeEventListener('reset', onFormReset); 194 + }, 195 }; 196 } 197
+1 -1
web_src/js/webcomponents/polyfills.js
··· 9 return { 10 format(value) { 11 return ` ${value} ${options.unit}`; 12 - } 13 }; 14 } 15 return intlNumberFormat(locales, options);
··· 9 return { 10 format(value) { 11 return ` ${value} ${options.unit}`; 12 + }, 13 }; 14 } 15 return intlNumberFormat(locales, options);
+3 -3
webpack.config.js
··· 182 ], 183 }, 184 }, 185 - } 186 ], 187 }, 188 { ··· 195 type: 'asset/resource', 196 generator: { 197 filename: 'fonts/[name].[contenthash:8][ext]', 198 - } 199 }, 200 { 201 test: /\.png$/i, 202 type: 'asset/resource', 203 generator: { 204 filename: 'img/webpack/[name].[contenthash:8][ext]', 205 - } 206 }, 207 ], 208 },
··· 182 ], 183 }, 184 }, 185 + }, 186 ], 187 }, 188 { ··· 195 type: 'asset/resource', 196 generator: { 197 filename: 'fonts/[name].[contenthash:8][ext]', 198 + }, 199 }, 200 { 201 test: /\.png$/i, 202 type: 'asset/resource', 203 generator: { 204 filename: 'img/webpack/[name].[contenthash:8][ext]', 205 + }, 206 }, 207 ], 208 },