From 902be92e50bfee176a8321190bcf9d4e63060ce5 Mon Sep 17 00:00:00 2001 From: wxiaoguang Date: Tue, 7 Mar 2023 12:59:26 +0800 Subject: [PATCH 01/24] fix --- options/locale/locale_en-US.ini | 1 - templates/repo/home.tmpl | 29 ++++++++++++++--------------- web_src/js/features/repo-home.js | 14 ++++++++++---- web_src/less/_base.less | 4 ++++ web_src/less/_repository.less | 4 ---- 5 files changed, 28 insertions(+), 24 deletions(-) diff --git a/options/locale/locale_en-US.ini b/options/locale/locale_en-US.ini index 3695bd0384aa9..8ffaf9ef2156c 100644 --- a/options/locale/locale_en-US.ini +++ b/options/locale/locale_en-US.ini @@ -2354,7 +2354,6 @@ tag.create_tag_from = Create new tag from '%s' tag.create_success = Tag '%s' has been created. topic.manage_topics = Manage Topics -topic.done = Done topic.count_prompt = You cannot select more than 25 topics topic.format_prompt = Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long. diff --git a/templates/repo/home.tmpl b/templates/repo/home.tmpl index 2a79c51ddf946..350c4b635d50e 100644 --- a/templates/repo/home.tmpl +++ b/templates/repo/home.tmpl @@ -29,26 +29,25 @@ {{end}}
- {{range .Topics}}{{.Name}}{{end}} - {{if and .Permission.IsAdmin (not .Repository.IsArchived)}}{{.locale.Tr "repo.topic.manage_topics"}}{{end}} + {{range .Topics}}{{.Name}}{{end}} + {{if and .Permission.IsAdmin (not .Repository.IsArchived)}}{{end}}
{{end}} {{if and .Permission.IsAdmin (not .Repository.IsArchived)}} -
-
-
- +
+
+
-
- {{.locale.Tr "repo.topic.done"}} +
+ +
{{end}} diff --git a/web_src/js/features/repo-home.js b/web_src/js/features/repo-home.js index dfccffc79488a..fa35ad5bfb3c9 100644 --- a/web_src/js/features/repo-home.js +++ b/web_src/js/features/repo-home.js @@ -10,12 +10,20 @@ export function initRepoTopicBar() { const viewDiv = $('#repo-topics'); const saveBtn = $('#save_topic'); const topicDropdown = $('#topic_edit .dropdown'); - const topicForm = $('#topic_edit.ui.form'); + const topicDropdownSearch = topicDropdown.find('input.search'); + const topicForm = $('#topic_edit'); const topicPrompts = getPrompts(); mgrBtn.on('click', () => { hideElem(viewDiv); showElem(editDiv); + topicDropdownSearch.focus(); + }); + + $('#cancel_topic_edit').on('click', () => { + hideElem(editDiv); + showElem(viewDiv); + mgrBtn.focus(); }); function getPrompts() { @@ -39,13 +47,11 @@ export function initRepoTopicBar() { viewDiv.children('.topic').remove(); if (topics.length) { const topicArray = topics.split(','); - - const last = viewDiv.children('a').last(); for (let i = 0; i < topicArray.length; i++) { const link = $(''); link.attr('href', `${appSubUrl}/explore/repos?q=${encodeURIComponent(topicArray[i])}&topic=1`); link.text(topicArray[i]); - link.insertBefore(last); + link.insertBefore(mgrBtn); // insert all new topics before manage button } } hideElem(editDiv); diff --git a/web_src/less/_base.less b/web_src/less/_base.less index 1cf65e784cd4d..8668141fa6239 100644 --- a/web_src/less/_base.less +++ b/web_src/less/_base.less @@ -2329,6 +2329,10 @@ a.ui.label:hover { color: var(--color-text); } +.ui.tertiary.button:focus { + color: var(--color-text-dark); +} + .ui.primary.label, .ui.primary.labels .label { background-color: var(--color-primary) !important; diff --git a/web_src/less/_repository.less b/web_src/less/_repository.less index 3b93a76a16ebc..29236d884e8da 100644 --- a/web_src/less/_repository.less +++ b/web_src/less/_repository.less @@ -3042,10 +3042,6 @@ tbody.commit-list { } } -#manage_topic { - font-size: 12px; -} - .label + #manage_topic { margin-left: 5px; } From c379fc5d7d62c964f2a0bb449852553e512ba464 Mon Sep 17 00:00:00 2001 From: wxiaoguang Date: Tue, 7 Mar 2023 23:16:35 +0800 Subject: [PATCH 02/24] add aria attributes to delete icon --- templates/repo/home.tmpl | 10 +++---- web_src/js/features/aria.js | 7 ++--- web_src/js/features/repo-home.js | 46 +++++++++++++++++--------------- 3 files changed, 34 insertions(+), 29 deletions(-) diff --git a/templates/repo/home.tmpl b/templates/repo/home.tmpl index 350c4b635d50e..649f5f62c3887 100644 --- a/templates/repo/home.tmpl +++ b/templates/repo/home.tmpl @@ -36,7 +36,11 @@ {{if and .Permission.IsAdmin (not .Repository.IsArchived)}}
- {{end}} -
- {{.locale.Tr "repo.topic.count_prompt"}} - {{.locale.Tr "repo.topic.format_prompt"}} -
{{if .Repository.IsArchived}}
{{.locale.Tr "repo.archive.title"}} diff --git a/web_src/js/features/aria.js b/web_src/js/features/aria.js index 373d667c5f73c..bbe00b9aaf9b2 100644 --- a/web_src/js/features/aria.js +++ b/web_src/js/features/aria.js @@ -6,14 +6,14 @@ function generateAriaId() { return `_aria_auto_id_${ariaIdCounter++}`; } -// make the item has role=option, and add an id if there wasn't one yet. +// make the item has role=menuitem/option, and add an id if there wasn't one yet. function prepareMenuItem($item) { if (!$item.attr('id')) $item.attr('id', generateAriaId()); $item.attr({'role': 'menuitem', 'tabindex': '-1'}); $item.find('a').attr('tabindex', '-1'); // as above, the elements inside the dropdown menu item should not be focusable, the focus should always be on the dropdown primary element. } -// when the menu items are loaded from AJAX requests, the items are created dynamically +// when the dropdown menu items are loaded from AJAX requests, the items are created dynamically const defaultCreateDynamicMenu = $.fn.dropdown.settings.templates.menu; $.fn.dropdown.settings.templates.menu = function(response, fields, preserveHTML, className) { const ret = defaultCreateDynamicMenu(response, fields, preserveHTML, className); @@ -33,7 +33,7 @@ function attachOneDropdownAria($dropdown) { const $focusable = $textSearch.length ? $textSearch : $dropdown; // see comment below if (!$focusable.length) return; - // prepare menu list + // prepare dropdown menu list const $menu = $dropdown.find('> .menu'); if (!$menu.attr('id')) $menu.attr('id', generateAriaId()); @@ -50,6 +50,7 @@ function attachOneDropdownAria($dropdown) { // - otherwise, the dropdown control (low-level code) handles the Enter event, hides the dropdown menu // TODO: multiple selection is not supported yet. + // TODO: use combobox for dropdown with search input in the future $focusable.attr({ 'role': 'menu', diff --git a/web_src/js/features/repo-home.js b/web_src/js/features/repo-home.js index fa35ad5bfb3c9..6ae301b023e2a 100644 --- a/web_src/js/features/repo-home.js +++ b/web_src/js/features/repo-home.js @@ -6,36 +6,39 @@ const {appSubUrl, csrfToken} = window.config; export function initRepoTopicBar() { const mgrBtn = $('#manage_topic'); - const editDiv = $('#topic_edit'); - const viewDiv = $('#repo-topics'); + if (!mgrBtn.length) return; + const saveBtn = $('#save_topic'); + const topicListDiv = $('#repo-topics'); const topicDropdown = $('#topic_edit .dropdown'); const topicDropdownSearch = topicDropdown.find('input.search'); const topicForm = $('#topic_edit'); - const topicPrompts = getPrompts(); + const topicPrompts = { + countPrompt: topicDropdown.attr('data-text-count-prompt'), + formatPrompt: topicDropdown.attr('data-text-format-prompt'), + remove: topicDropdown.attr('data-text-remove'), + }; + + function addLabelDeleteIconAria($el) { + $el.attr({ + 'aria-label': topicPrompts.remove, + 'role': 'button', + }); + } mgrBtn.on('click', () => { - hideElem(viewDiv); - showElem(editDiv); + hideElem(topicListDiv); + showElem(topicForm); + addLabelDeleteIconAria(topicDropdown.find('i.delete.icon')); topicDropdownSearch.focus(); }); $('#cancel_topic_edit').on('click', () => { - hideElem(editDiv); - showElem(viewDiv); + hideElem(topicForm); + showElem(topicListDiv); mgrBtn.focus(); }); - function getPrompts() { - const hidePrompt = $('#validate_prompt'); - const prompts = { - countPrompt: hidePrompt.children('#count_prompt').text(), - formatPrompt: hidePrompt.children('#format_prompt').text() - }; - hidePrompt.remove(); - return prompts; - } - saveBtn.on('click', () => { const topics = $('input[name=topics]').val(); @@ -44,7 +47,7 @@ export function initRepoTopicBar() { topics }, (_data, _textStatus, xhr) => { if (xhr.responseJSON.status === 'ok') { - viewDiv.children('.topic').remove(); + topicListDiv.children('.topic').remove(); if (topics.length) { const topicArray = topics.split(','); for (let i = 0; i < topicArray.length; i++) { @@ -54,8 +57,8 @@ export function initRepoTopicBar() { link.insertBefore(mgrBtn); // insert all new topics before manage button } } - hideElem(editDiv); - showElem(viewDiv); + hideElem(topicForm); + showElem(topicListDiv); } }).fail((xhr) => { if (xhr.status === 422) { @@ -147,7 +150,8 @@ export function initRepoTopicBar() { onLabelCreate(value) { value = value.toLowerCase().trim(); this.attr('data-value', value).contents().first().replaceWith(value); - return $(this); + addLabelDeleteIconAria(this.find('i.delete.icon')); + return this; }, onAdd(addedValue, _addedText, $addedChoice) { addedValue = addedValue.toLowerCase().trim(); From 5dd48bb88e8a3da0fbb18e4a52ab56957c3e68ec Mon Sep 17 00:00:00 2001 From: wxiaoguang Date: Tue, 7 Mar 2023 23:55:12 +0800 Subject: [PATCH 03/24] make "delete icon button" slightly larger to be easier to click on mobile --- web_src/js/features/repo-home.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/web_src/js/features/repo-home.js b/web_src/js/features/repo-home.js index 6ae301b023e2a..e8c3cb77206bf 100644 --- a/web_src/js/features/repo-home.js +++ b/web_src/js/features/repo-home.js @@ -23,7 +23,7 @@ export function initRepoTopicBar() { $el.attr({ 'aria-label': topicPrompts.remove, 'role': 'button', - }); + }).addClass('gt-px-2'); // make it slightly larger to be easier to click on mobile } mgrBtn.on('click', () => { From 25f993b1a8a1077a107107e93cb5eae65d430c2b Mon Sep 17 00:00:00 2001 From: wxiaoguang Date: Tue, 7 Mar 2023 23:57:54 +0800 Subject: [PATCH 04/24] fix lint --- templates/repo/home.tmpl | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/templates/repo/home.tmpl b/templates/repo/home.tmpl index 649f5f62c3887..4cffef76d596a 100644 --- a/templates/repo/home.tmpl +++ b/templates/repo/home.tmpl @@ -37,9 +37,9 @@
diff --git a/web_src/js/features/repo-home.js b/web_src/js/features/repo-home.js index e8c3cb77206bf..7b6d05275298f 100644 --- a/web_src/js/features/repo-home.js +++ b/web_src/js/features/repo-home.js @@ -1,6 +1,7 @@ import $ from 'jquery'; import {stripTags} from '../utils.js'; import {hideElem, showElem} from '../utils/dom.js'; +import {htmlEscape} from 'escape-goat'; const {appSubUrl, csrfToken} = window.config; @@ -110,7 +111,7 @@ export function initRepoTopicBar() { const query = stripTags(this.urlData.query.trim()); let found_query = false; const current_topics = []; - topicDropdown.find('div.label.visible.topic,a.label.visible').each((_, el) => { + topicDropdown.find('div.label.visible.topic').each((_, el) => { current_topics.push(el.getAttribute('data-value')); }); @@ -149,9 +150,10 @@ export function initRepoTopicBar() { }, onLabelCreate(value) { value = value.toLowerCase().trim(); - this.attr('data-value', value).contents().first().replaceWith(value); - addLabelDeleteIconAria(this.find('i.delete.icon')); - return this; + // keep the same as template (repo-topic-label) + const $el = $(`
${htmlEscape(value)}
`); + addLabelDeleteIconAria($el.find('i.delete.icon')); + return $el; }, onAdd(addedValue, _addedText, $addedChoice) { addedValue = addedValue.toLowerCase().trim(); From 77ee1f1968498134f3fa69617611458d4527a343 Mon Sep 17 00:00:00 2001 From: wxiaoguang Date: Wed, 8 Mar 2023 00:11:42 +0800 Subject: [PATCH 06/24] add more comments --- web_src/js/features/repo-home.js | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/web_src/js/features/repo-home.js b/web_src/js/features/repo-home.js index 7b6d05275298f..634be56e561bc 100644 --- a/web_src/js/features/repo-home.js +++ b/web_src/js/features/repo-home.js @@ -150,8 +150,9 @@ export function initRepoTopicBar() { }, onLabelCreate(value) { value = value.toLowerCase().trim(); - // keep the same as template (repo-topic-label) - const $el = $(`
${htmlEscape(value)}
`); + // `this` is the default label jQuery element, it's "" + // we create a new div element to replace it, to keep the same as template (repo-topic-label), because we do not want the `` tag to affect aria focus. + const $el = $(`
${htmlEscape(value)}
`); addLabelDeleteIconAria($el.find('i.delete.icon')); return $el; }, From 5e9aa1eb38fd229f07889e2a2fa9273b33fb3338 Mon Sep 17 00:00:00 2001 From: wxiaoguang Date: Wed, 8 Mar 2023 02:11:06 +0800 Subject: [PATCH 07/24] use svg, fine tune styles --- templates/repo/home.tmpl | 9 ++++----- web_src/js/features/repo-home.js | 13 +++++++------ web_src/less/_repository.less | 25 +++---------------------- web_src/less/helpers.less | 1 + 4 files changed, 15 insertions(+), 33 deletions(-) diff --git a/templates/repo/home.tmpl b/templates/repo/home.tmpl index 837cb67436752..eacd1c2ff6205 100644 --- a/templates/repo/home.tmpl +++ b/templates/repo/home.tmpl @@ -28,9 +28,9 @@
{{end}}
-
+
{{range .Topics}}{{.Name}}{{end}} - {{if and .Permission.IsAdmin (not .Repository.IsArchived)}}{{end}} + {{if and .Permission.IsAdmin (not .Repository.IsArchived)}}{{end}}
{{end}} {{if and .Permission.IsAdmin (not .Repository.IsArchived)}} @@ -43,9 +43,8 @@ > {{range .Topics}} - {{/* lalels generated by Fomantic still use ``, to avoid mixing different style together and to remind future developers, use it instead of svg - and keep the same as template (repo-topic-label), the style is also added by Fomantic Dropdown automatically when generating new labels */}} -
{{.Name}}
+ {{/* keep the same as template (repo-topic-label), the style "display" is also added by Fomantic Dropdown automatically when generating new labels */}} +
{{.Name}}{{svg "octicon-x" 16 "delete icon gt-ml-3 gt-mt-1"}}
{{end}}
diff --git a/web_src/js/features/repo-home.js b/web_src/js/features/repo-home.js index 634be56e561bc..3af1d20a71268 100644 --- a/web_src/js/features/repo-home.js +++ b/web_src/js/features/repo-home.js @@ -2,6 +2,7 @@ import $ from 'jquery'; import {stripTags} from '../utils.js'; import {hideElem, showElem} from '../utils/dom.js'; import {htmlEscape} from 'escape-goat'; +import {svg} from '../svg.js'; const {appSubUrl, csrfToken} = window.config; @@ -21,16 +22,16 @@ export function initRepoTopicBar() { }; function addLabelDeleteIconAria($el) { - $el.attr({ + $el.removeAttr('aria-hidden').attr({ 'aria-label': topicPrompts.remove, 'role': 'button', - }).addClass('gt-px-2'); // make it slightly larger to be easier to click on mobile + }); } mgrBtn.on('click', () => { hideElem(topicListDiv); showElem(topicForm); - addLabelDeleteIconAria(topicDropdown.find('i.delete.icon')); + addLabelDeleteIconAria(topicDropdown.find('.delete.icon')); topicDropdownSearch.focus(); }); @@ -151,9 +152,9 @@ export function initRepoTopicBar() { onLabelCreate(value) { value = value.toLowerCase().trim(); // `this` is the default label jQuery element, it's "" - // we create a new div element to replace it, to keep the same as template (repo-topic-label), because we do not want the `` tag to affect aria focus. - const $el = $(`
${htmlEscape(value)}
`); - addLabelDeleteIconAria($el.find('i.delete.icon')); + // we create a new div element to replace it, to keep the same as template (repo-topic-label), because we do not want the `
` tag which affects aria focus. + const $el = $(`
${htmlEscape(value)}${svg('octicon-x', 16, 'delete icon gt-ml-3 gt-mt-1')}
`); + addLabelDeleteIconAria($el.find('.delete.icon')); return $el; }, onAdd(addedValue, _addedText, $addedChoice) { diff --git a/web_src/less/_repository.less b/web_src/less/_repository.less index 29236d884e8da..61c18e7aa11f8 100644 --- a/web_src/less/_repository.less +++ b/web_src/less/_repository.less @@ -3010,21 +3010,10 @@ tbody.commit-list { top: -2px; } -#topic_edit { - margin-top: 5px; -} - -#repo-topics { - margin-top: 5px; - display: flex; - align-items: center; - flex-wrap: wrap; -} - -.repo-topic { - font-weight: normal !important; +#repo-topics .repo-topic { + font-weight: normal; cursor: pointer; - margin: 2px !important; + margin: 2px; } #new-dependency-drop-list { @@ -3042,14 +3031,6 @@ tbody.commit-list { } } -.label + #manage_topic { - margin-left: 5px; -} - -.ui.small.label.topic { - margin-bottom: 4px; -} - .repo-header { display: flex; align-items: center; diff --git a/web_src/less/helpers.less b/web_src/less/helpers.less index baa5959946e82..9feabde8cec1b 100644 --- a/web_src/less/helpers.less +++ b/web_src/less/helpers.less @@ -21,6 +21,7 @@ /* below class names match Tailwind CSS */ .gt-pointer-events-none { pointer-events: none !important; } .gt-relative { position: relative !important; } +.gt-cursor-default { cursor: default !important; } .gt-mono { font-family: var(--fonts-monospace) !important; From a1e35b40821274d99dcc3bf1f7f53eaae24dec7a Mon Sep 17 00:00:00 2001 From: wxiaoguang Date: Wed, 8 Mar 2023 14:21:55 +0800 Subject: [PATCH 08/24] title: Remove topic "%s" --- options/locale/locale_en-US.ini | 1 + templates/repo/home.tmpl | 2 +- web_src/js/features/repo-home.js | 4 ++-- 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/options/locale/locale_en-US.ini b/options/locale/locale_en-US.ini index 8ffaf9ef2156c..96c01529d89ab 100644 --- a/options/locale/locale_en-US.ini +++ b/options/locale/locale_en-US.ini @@ -2356,6 +2356,7 @@ tag.create_success = Tag '%s' has been created. topic.manage_topics = Manage Topics topic.count_prompt = You cannot select more than 25 topics topic.format_prompt = Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long. +topic.remove_topic = Remove topic "%s" find_file.go_to_file = Go to file find_file.no_matching = No matching file found diff --git a/templates/repo/home.tmpl b/templates/repo/home.tmpl index eacd1c2ff6205..11c00653da854 100644 --- a/templates/repo/home.tmpl +++ b/templates/repo/home.tmpl @@ -39,7 +39,7 @@