Restore #10096/#8638 and re-fix #15172 (#16576) (#16617)

Backport #16576

This PR restores the vendored and patched dropdow from #8638. It
however, it partially abandons the call to `click()` using instead the
default dropdown click calls instead. This prevents the issue of the
dropdown grabbing focus permanently however, this may have negative
effects on the effect of focus on the dropdowns.

Of note, the behaviour of the template selector dropdown on the repo
creation page is slightly odd - I don't believe that this odd behaviour
is caused by this PR but rather by the feed source for this. I suspect
that the dropdown should be adding a delete button to its selection.

Fix #15172
References: #7057

Signed-off-by: Andrew Thornton <art27@cantab.net>
release/v1.15
zeripath 2021-08-04 13:31:10 +01:00 committed by GitHub
parent f9120092c1
commit 40687a2160
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 4450 additions and 10 deletions

View File

@ -2,6 +2,7 @@ root: true
reportUnusedDisableDirectives: true reportUnusedDisableDirectives: true
ignorePatterns: ignorePatterns:
- /web_src/js/vendor
- /templates/base/head.tmpl - /templates/base/head.tmpl
- /templates/repo/activity.tmpl - /templates/repo/activity.tmpl
- /templates/repo/view_file.tmpl - /templates/repo/view_file.tmpl

View File

@ -699,6 +699,7 @@ fomantic:
cd $(FOMANTIC_WORK_DIR) && npm install --no-save cd $(FOMANTIC_WORK_DIR) && npm install --no-save
cp -f $(FOMANTIC_WORK_DIR)/theme.config.less $(FOMANTIC_WORK_DIR)/node_modules/fomantic-ui/src/theme.config cp -f $(FOMANTIC_WORK_DIR)/theme.config.less $(FOMANTIC_WORK_DIR)/node_modules/fomantic-ui/src/theme.config
cp -rf $(FOMANTIC_WORK_DIR)/_site $(FOMANTIC_WORK_DIR)/node_modules/fomantic-ui/src/ cp -rf $(FOMANTIC_WORK_DIR)/_site $(FOMANTIC_WORK_DIR)/node_modules/fomantic-ui/src/
cp -f web_src/js/vendor/dropdown.js $(FOMANTIC_WORK_DIR)/node_modules/fomantic-ui/src/definitions/modules
cd $(FOMANTIC_WORK_DIR) && npx gulp -f node_modules/fomantic-ui/gulpfile.js build cd $(FOMANTIC_WORK_DIR) && npx gulp -f node_modules/fomantic-ui/gulpfile.js build
.PHONY: webpack .PHONY: webpack

View File

@ -30873,7 +30873,7 @@ ol.ui.suffixed.list li:before,
List List
---------------*/ ---------------*/
/* Menu divider shouldn't apply */ /* Menu divider shouldnt apply */
.ui.menu .list .item:before { .ui.menu .list .item:before {
background: none !important; background: none !important;
@ -31802,7 +31802,7 @@ Floated Menu / Item
opacity: 1; opacity: 1;
} }
/* Icon Glyph */ /* Icon Gylph */
.ui.icon.menu i.icon:before { .ui.icon.menu i.icon:before {
opacity: 1; opacity: 1;

View File

@ -142,7 +142,7 @@ $.api = $.fn.api = function(parameters) {
response = JSON.parse(response); response = JSON.parse(response);
} }
catch(e) { catch(e) {
// isn't json string // isnt json string
} }
} }
return response; return response;
@ -2220,7 +2220,7 @@ $.fn.dimmer = function(parameters) {
event: { event: {
click: function(event) { click: function(event) {
module.verbose('Determining if event occurred on dimmer', event); module.verbose('Determining if event occured on dimmer', event);
if( $dimmer.find(event.target).length === 0 || $(event.target).is(selector.content) ) { if( $dimmer.find(event.target).length === 0 || $(event.target).is(selector.content) ) {
module.hide(); module.hide();
event.stopImmediatePropagation(); event.stopImmediatePropagation();
@ -2827,6 +2827,13 @@ $.fn.dimmer.settings = {
* *
*/ */
/*
* Copyright 2019 The Gitea Authors
* Released under the MIT license
* http://opensource.org/licenses/MIT
* This version has been modified by Gitea to improve accessibility.
*/
;(function ($, window, document, undefined) { ;(function ($, window, document, undefined) {
'use strict'; 'use strict';
@ -2860,6 +2867,7 @@ $.fn.dropdown = function(parameters) {
query = arguments[0], query = arguments[0],
methodInvoked = (typeof query == 'string'), methodInvoked = (typeof query == 'string'),
queryArguments = [].slice.call(arguments, 1), queryArguments = [].slice.call(arguments, 1),
lastAriaID = 1,
returnedValue returnedValue
; ;
@ -2952,6 +2960,8 @@ $.fn.dropdown = function(parameters) {
module.observeChanges(); module.observeChanges();
module.instantiate(); module.instantiate();
module.aria.setup();
} }
}, },
@ -3152,6 +3162,86 @@ $.fn.dropdown = function(parameters) {
} }
}, },
aria: {
setup: function() {
var role = module.aria.guessRole();
if( role !== 'menu' ) {
return;
}
$module.attr('aria-busy', 'true');
$module.attr('role', 'menu');
$module.attr('aria-haspopup', 'menu');
$module.attr('aria-expanded', 'false');
$menu.find('.divider').attr('role', 'separator');
$item.attr('role', 'menuitem');
$item.each(function (index, item) {
if( !item.id ) {
item.id = module.aria.nextID('menuitem');
}
});
$text = $module
.find('> .text')
.eq(0)
;
if( $module.data('content') ) {
$text.attr('aria-hidden');
$module.attr('aria-label', $module.data('content'));
}
else {
$text.attr('id', module.aria.nextID('menutext'));
$module.attr('aria-labelledby', $text.attr('id'));
}
$module.attr('aria-busy', 'false');
},
nextID: function(prefix) {
var nextID;
do {
nextID = prefix + '_' + lastAriaID++;
} while( document.getElementById(nextID) );
return nextID;
},
setExpanded: function(expanded) {
if( $module.attr('aria-haspopup') ) {
$module.attr('aria-expanded', expanded);
}
},
refreshDescendant: function() {
if( $module.attr('aria-haspopup') !== 'menu' ) {
return;
}
var
$currentlySelected = $item.not(selector.unselectable).filter('.' + className.selected).eq(0),
$activeItem = $menu.children('.' + className.active).eq(0),
$selectedItem = ($currentlySelected.length > 0)
? $currentlySelected
: $activeItem
;
if( $selectedItem ) {
$module.attr('aria-activedescendant', $selectedItem.attr('id'));
}
else {
module.aria.removeDescendant();
}
},
removeDescendant: function() {
if( $module.attr('aria-haspopup') == 'menu' ) {
$module.removeAttr('aria-activedescendant');
}
},
guessRole: function() {
var
isIcon = $module.hasClass('icon'),
hasSearch = module.has.search(),
hasInput = ($input.length > 0),
isMultiple = module.is.multiple()
;
if ( !isIcon && !hasSearch && !hasInput && !isMultiple ) {
return 'menu';
}
return 'unknown';
}
},
setup: { setup: {
api: function() { api: function() {
var var
@ -3198,6 +3288,7 @@ $.fn.dropdown = function(parameters) {
if(settings.allowTab) { if(settings.allowTab) {
module.set.tabbable(); module.set.tabbable();
} }
$item.attr('tabindex', '-1');
}, },
select: function() { select: function() {
var var
@ -3344,6 +3435,8 @@ $.fn.dropdown = function(parameters) {
return true; return true;
} }
if(settings.onShow.call(element) !== false) { if(settings.onShow.call(element) !== false) {
module.aria.setExpanded(true);
module.aria.refreshDescendant();
module.animate.show(function() { module.animate.show(function() {
if( module.can.click() ) { if( module.can.click() ) {
module.bind.intent(); module.bind.intent();
@ -3366,9 +3459,11 @@ $.fn.dropdown = function(parameters) {
if( module.is.active() && !module.is.animatingOutward() ) { if( module.is.active() && !module.is.animatingOutward() ) {
module.debug('Hiding dropdown'); module.debug('Hiding dropdown');
if(settings.onHide.call(element) !== false) { if(settings.onHide.call(element) !== false) {
module.aria.setExpanded(false);
module.aria.removeDescendant();
module.animate.hide(function() { module.animate.hide(function() {
module.remove.visible(); module.remove.visible();
// hiding search focus // hidding search focus
if ( module.is.focusedOnSearch() && preventBlur !== true ) { if ( module.is.focusedOnSearch() && preventBlur !== true ) {
$search.blur(); $search.blur();
} }
@ -4319,7 +4414,7 @@ $.fn.dropdown = function(parameters) {
// allow selection with menu closed // allow selection with menu closed
if(isAdditionWithoutMenu) { if(isAdditionWithoutMenu) {
module.verbose('Selecting item from keyboard shortcut', $selectedItem); module.verbose('Selecting item from keyboard shortcut', $selectedItem);
module.event.item.click.call($selectedItem, event); $selectedItem[0].click();
if(module.is.searchSelection()) { if(module.is.searchSelection()) {
module.remove.searchTerm(); module.remove.searchTerm();
} }
@ -4339,7 +4434,7 @@ $.fn.dropdown = function(parameters) {
} }
else if(selectedIsSelectable) { else if(selectedIsSelectable) {
module.verbose('Selecting item from keyboard shortcut', $selectedItem); module.verbose('Selecting item from keyboard shortcut', $selectedItem);
module.event.item.click.call($selectedItem, event); $selectedItem[0].click();
if(module.is.searchSelection()) { if(module.is.searchSelection()) {
module.remove.searchTerm(); module.remove.searchTerm();
if(module.is.multiple()) { if(module.is.multiple()) {
@ -4367,6 +4462,7 @@ $.fn.dropdown = function(parameters) {
.closest(selector.item) .closest(selector.item)
.addClass(className.selected) .addClass(className.selected)
; ;
module.aria.refreshDescendant();
event.preventDefault(); event.preventDefault();
} }
} }
@ -4383,6 +4479,7 @@ $.fn.dropdown = function(parameters) {
.find(selector.item).eq(0) .find(selector.item).eq(0)
.addClass(className.selected) .addClass(className.selected)
; ;
module.aria.refreshDescendant();
event.preventDefault(); event.preventDefault();
} }
} }
@ -4407,6 +4504,7 @@ $.fn.dropdown = function(parameters) {
$nextItem $nextItem
.addClass(className.selected) .addClass(className.selected)
; ;
module.aria.refreshDescendant();
module.set.scrollPosition($nextItem); module.set.scrollPosition($nextItem);
if(settings.selectOnKeydown && module.is.single()) { if(settings.selectOnKeydown && module.is.single()) {
module.set.selectedItem($nextItem); module.set.selectedItem($nextItem);
@ -4434,6 +4532,7 @@ $.fn.dropdown = function(parameters) {
$nextItem $nextItem
.addClass(className.selected) .addClass(className.selected)
; ;
module.aria.refreshDescendant();
module.set.scrollPosition($nextItem); module.set.scrollPosition($nextItem);
if(settings.selectOnKeydown && module.is.single()) { if(settings.selectOnKeydown && module.is.single()) {
module.set.selectedItem($nextItem); module.set.selectedItem($nextItem);
@ -5403,6 +5502,7 @@ $.fn.dropdown = function(parameters) {
module.set.scrollPosition($nextValue); module.set.scrollPosition($nextValue);
$selectedItem.removeClass(className.selected); $selectedItem.removeClass(className.selected);
$nextValue.addClass(className.selected); $nextValue.addClass(className.selected);
module.aria.refreshDescendant();
if(settings.selectOnKeydown && module.is.single()) { if(settings.selectOnKeydown && module.is.single()) {
module.set.selectedItem($nextValue); module.set.selectedItem($nextValue);
} }
@ -11937,7 +12037,7 @@ $.fn.progress = function(parameters) {
* *
* @param min A minimum value within multiple values * @param min A minimum value within multiple values
* @param total A total amount of multiple values * @param total A total amount of multiple values
* @returns {number} A precision. Could be 1, 10, 100, ... 1e+10. * @returns {number} A precison. Could be 1, 10, 100, ... 1e+10.
*/ */
derivePrecision: function(min, total) { derivePrecision: function(min, total) {
var precisionPower = 0 var precisionPower = 0
@ -12837,7 +12937,7 @@ $.fn.progress.settings = {
nonNumeric : 'Progress value is non numeric', nonNumeric : 'Progress value is non numeric',
tooHigh : 'Value specified is above 100%', tooHigh : 'Value specified is above 100%',
tooLow : 'Value specified is below 0%', tooLow : 'Value specified is below 0%',
sumExceedsTotal : 'Sum of multiple values exceed total', sumExceedsTotal : 'Sum of multple values exceed total',
}, },
regExp: { regExp: {
@ -18076,7 +18176,7 @@ $.fn.transition.settings = {
// possible errors // possible errors
error: { error: {
noAnimation : 'Element is no longer attached to DOM. Unable to animate. Use silent setting to suppress this warning in production.', noAnimation : 'Element is no longer attached to DOM. Unable to animate. Use silent setting to surpress this warning in production.',
repeated : 'That animation is already occurring, cancelling repeated animation', repeated : 'That animation is already occurring, cancelling repeated animation',
method : 'The method you called is not defined', method : 'The method you called is not defined',
support : 'This browser does not support CSS animations' support : 'This browser does not support CSS animations'

4338
web_src/js/vendor/dropdown.js vendored Normal file

File diff suppressed because it is too large Load Diff