Apply accessibility changes to all dropdowns

This commit is contained in:
yflory 2023-11-23 16:48:39 +01:00
parent 7fc3ff94a9
commit 31c3148580
11 changed files with 243 additions and 431 deletions

View File

@ -546,7 +546,7 @@
}
li {
cursor: default;
&:not(.cp-app-drive-element-header) {
&:not(.cp-app-drive-element-header):not([role="menuitem"]) {
&:hover {
&:not(.-cp-app-drive-element-selected, .cp-app-drive-element-selected-tmp) {
background-color: @cp_drive-icon-hover;

View File

@ -116,11 +116,6 @@
margin-right: 5px !important;
}
&:hover {
background-color: @cp_dropdown-bg-hover;
color: @cp_dropdown-fg;
}
&.cp-dropdown-element-active {
background-color: @cp_dropdown-bg-active;
color: @cp_dropdown-fg;
@ -135,60 +130,12 @@
}
}
}
& > a, & > span {
color: @cp_dropdown-fg;
li[role="menuitem"] {
border-radius: @variables_radius;
padding: 5px;
text-decoration: none;
display: flex;
cursor: pointer;
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
float: none;
text-align: left;
line-height: 1em;
align-items: center;
&:not(.fa) {
font: @dropdown_font;
}
&.fa, &.cptools {
font-size: 18px;
&::before {
width: 40px;
margin-left: -10px;
text-align: center;
}
* {
font: @dropdown_font;
}
}
.fa, .cptools {
width: 20px;
text-align: center;
margin-right: 5px !important;
}
&:hover {
background-color: @cp_dropdown-bg-hover;
&:hover, &:focus {
background-color: @cp_dropdown-bg-hover !important;
color: @cp_dropdown-fg;
}
&.cp-dropdown-element-active {
background-color: @cp_dropdown-bg-active;
color: @cp_dropdown-fg;
}
&.cp-app-hidden {
display: none;
}
&.cp-app-disabled {
cursor: not-allowed !important;
opacity: 0.5;
}
}
&> span {
box-sizing: border-box;
@ -225,6 +172,9 @@
display: none;
}
}
[role="separator"] + [role="separator"] {
display: none;
}
p {
min-width: 160px;

View File

@ -65,10 +65,13 @@
}
}
.cp-notifications-gotoapp {
padding: 0 !important;
justify-content: center !important;
p {
padding: 10px 0 !important;
text-align: center !important;
font-weight: bold;
font-size: 14px !important;
font-weight: bold !important;
cursor: pointer;
&:hover {
background-color: @cp_dropdown-bg-hover;

View File

@ -867,7 +867,7 @@
margin-left: 10px;
}
}
li.cp-toolbar-account {
div.cp-toolbar-account {
&> span {
font-weight: bold;
span {

View File

@ -719,7 +719,7 @@ define([
options: options, // Entries displayed in the menu
common: common,
buttonCls: 'btn btn-default fa fa-gear small cp-calendar-actions',
ariaLabel: Messages.calendar_settings,
buttonTitle: Messages.calendar_settings,
};
return UIElements.createDropdown(dropdownConfig)[0];
};
@ -1173,9 +1173,7 @@ ICS ==> create a new event with the same UID and a RECURRENCE-ID field (with a v
};
var $block = UIElements.createDropdown(dropdownConfig);
$block.setValue(view || 'week');
var $views = $block.find('a');
$views.click(function () {
var mode = $(this).attr('data-value');
$block.onChange.reg((name, mode) => {
cal.changeView(mode);
updateDateRange();
updateRecurring();
@ -1877,9 +1875,7 @@ APP.recurrenceRule = {
var $block = UIElements.createDropdown(dropdownConfig);
$block.setValue('minutes');
var $types = $block.find('a');
$types.click(function () {
var mode = $(this).attr('data-value');
$block.onChange.reg((name, mode) => {
var max = mode === "minutes" ? 60 : 24;
$number.attr('max', max);
if ($number.val() > max) { $number.val(max); }

View File

@ -20,18 +20,17 @@ define([
};
Msg.initSelector = function ($select, sfcommon) {
var selector = $select || $('#cp-language-selector');
var $selector = $select || $('#cp-language-selector');
if (!selector.length) { return; }
if (!$selector.length) { return; }
var language = Messages._getLanguage();
// Select the current language in the list
selector.setValue(language || 'en');
$selector.setValue(language || 'en');
// Listen for language change
$(selector).find('a.cp-language-value').on('click', function () {
var newLanguage = $(this).attr('data-value');
$selector.onChange.reg((prettyName, newLanguage) => {
Msg.setLanguage(newLanguage, sfcommon && sfcommon.getSframeChannel(), function () {
if (newLanguage !== language) {
if (sfcommon) {
@ -42,6 +41,7 @@ define([
}
});
});
};
Msg.applyTranslation = function () {

View File

@ -1491,14 +1491,20 @@ define([
if (config.buttonContent) {
$button = $(h('button', {
class: config.buttonCls || '',
'aria-label': config.ariaLabel || '',
'aria-haspopup': 'menu',
'aria-expanded': 'false',
'title': config.buttonTitle || '',
'aria-label': config.buttonTitle || '',
}, [
h('span.cp-dropdown-button-title', config.buttonContent),
]));
} else {
$button = $('<button>', {
'class': config.buttonCls || '',
'aria-label': config.ariaLabel || '',
'aria-haspopup': 'menu',
'aria-expanded': 'false',
'title': config.buttonTitle || '',
'aria-label': config.buttonTitle || '',
}).append($('<span>', {'class': 'cp-dropdown-button-title'}).text(config.text || ""));
}
@ -1522,18 +1528,26 @@ define([
window.setTimeout(function () { $innerblock.hide(); }, 0);
};
// When the menu is collapsed, update aria-expanded
var observer = new MutationObserver(function (mutations) {
mutations.forEach(function (mutation) {
if (mutation.attributeName !== 'style') { return; }
if ($innerblock[0].style.display === 'none') {
$button.attr('aria-expanded', 'false');
}
});
});
observer.observe($innerblock[0], { attributes: true });
// Add the dropdown content
var setOptions = function (options) {
options.forEach(function (o) {
if (!isValidOption(o)) { return; }
if (isElement(o)) { return $innerblock.append(o); }
if (isElement(o)) { return void $innerblock.append(o); }
var $el = $(h(o.tag, (o.attributes || {})));
if (typeof(o.content) === 'string' || (o.content instanceof Element)) {
o.content = [o.content];
}
if(typeof (o.content) === 'object' && !Array.isArray(o.content)) {
o.content = [o.content];
}
if (Array.isArray(o.content)) {
o.content.forEach(function (item) {
if (item instanceof Element) {
@ -1542,47 +1556,51 @@ define([
if (typeof(item) === 'string') {
$el[0].appendChild(document.createTextNode(item));
}
if (typeof item === 'object') {
// case where item is an object, eg: an <a> tag
var $subElement = $(h(item.tag, item.attributes || {}));
if (Array.isArray(item.content)) {
item.content.forEach(function (subItem) {
if (typeof subItem === 'string') {
$subElement[0].appendChild(document.createTextNode(subItem));
} else if (subItem instanceof Element) {
$subElement.append(subItem);
}
});
} else if (typeof item.content === 'string') {
$subElement.text(item.content);
} else if (item.content instanceof Element) {
$subElement.append(item.content);
}
$el.append($subElement);
}
});
// array of elements or text nodes
}
$el.appendTo($innerblock);
$el.on('click keydown', function (e) {
if (e.type === 'click' || (e.type === 'keydown' && e.keyCode === 13) || (e.type === 'keydown' && e.keyCode === 32)) {
if (Array.isArray(o.content)) {
o.content.forEach(function (item) {
if (typeof item === 'object') {
var close = item.action(e);
if (close) {
hide();
}
}
});
// Everything is added as an "li" tag
// Links and items with action are focusable
// Add correct "role" attribute
var $li = $(h('li'));
if (o.tag === 'a') {
$el.attr('tabindex', '-1');
$li.attr('role', 'menuitem');
$li.attr('tabindex', '0');
} else if (o.tag === 'li') {
$li = $el;
$li.attr('role', 'menuitem');
$li.attr('tabindex', '0');
} else if (o.tag === 'hr') {
$li.attr('role', 'separator');
} else {
$li.attr('role', 'none');
}
$li.append($el);
$li.appendTo($innerblock);
// Action can be triggered with a click or keyboard event
if (o.tag !== 'a' && o.tag !== 'li') { return; }
$li.on('mouseenter', (e) => {
console.error($li);
e.stopPropagation();
$li.focus();
});
var onAction = function (e) {
if (config.isSelect) { return; }
if (e.type === 'click' || (e.type === 'keydown' && e.keyCode === 13) || (e.type === 'keydown' && e.keyCode === 32)) {
e.stopPropagation();
if (typeof(o.action) === "function") {
var close = o.action(e);
if (close) { hide(); }
} else {
// Click on <a> with an href
if (e.type === 'keydown') { $el.get(0).click(); }
}
}
});
};
$li.on('click keydown', onAction);
});
};
setOptions(config.options);
@ -1599,6 +1617,11 @@ define([
if ($el.length !== 1) { return; }
$innerblock.find('.cp-dropdown-element-active').removeClass('cp-dropdown-element-active');
$el.addClass('cp-dropdown-element-active');
$el.closest('li').focus();
};
var setFocus = function ($el) {
if ($el.length !== 1) { return; }
$el.focus();
var scroll = $el.position().top + $innerblock.scrollTop();
if (scroll < $innerblock.scrollTop()) {
$innerblock.scrollTop(scroll);
@ -1611,6 +1634,7 @@ define([
var wh = $(window).height();
var button = $button[0].getBoundingClientRect();
var topPos = button.bottom;
$button.attr('aria-expanded', 'true');
$innerblock.css('bottom', '');
if (config.noscroll) {
var h = $innerblock.outerHeight();
@ -1622,6 +1646,7 @@ define([
}
$innerblock.show();
$innerblock.find('.cp-dropdown-element-active').removeClass('cp-dropdown-element-active');
setTimeout(() => {
if (config.isSelect && value) {
// We use JSON.stringify here to escape quotes
if (typeof(value) === "object") { value = JSON.stringify(value); }
@ -1630,7 +1655,10 @@ define([
try {
$innerblock.scrollTop($val.position().top + $innerblock.scrollTop());
} catch (e) {}
} else {
setFocus($innerblock.find('[role="menuitem"]').first());
}
});
if (config.feedback) { Feedback.send(config.feedback); }
};
@ -1644,6 +1672,7 @@ define([
if (!state) {
$c.addClass('cp-dropdown-visible');
}
try {
$('iframe').each(function (idx, ifrw) {
$(ifrw).contents().find('.cp-dropdown-content').hide();
@ -1659,71 +1688,14 @@ define([
});
if (config.isSelect) {
var pressed = '';
var to;
$container.onChange = Util.mkEvent();
$container.on('click', 'a', function () {
value = $(this).data('value');
var $val = $(this);
$container.on('click', 'li', function () {
var $val = $(this).find('a');
value = $val.data('value');
var textValue = $val.text() || value;
$button.find('.cp-dropdown-button-title').text(textValue);
$container.onChange.fire(textValue, value);
});
$container.keydown(function (e) {
var $value = $innerblock.find('[data-value].cp-dropdown-element-active:visible');
if (!$value.length) {
$value = $innerblock.find('[data-value]').first();
}
if (e.which === 38) { // Up
e.preventDefault();
e.stopPropagation();
if ($value.length) {
$value.mouseleave();
var $prev = $value.prev();
$prev.mouseenter();
setActive($prev);
}
}
if (e.which === 40) { // Down
e.preventDefault();
e.stopPropagation();
if ($value.length) {
$value.mouseleave();
var $next = $value.next();
$next.mouseenter();
setActive($next);
}
}
if (e.which === 13) { //Enter
e.preventDefault();
e.stopPropagation();
if ($value.length) {
$value.click();
hide();
}
}
if (e.which === 27) { // Esc
e.preventDefault();
e.stopPropagation();
$value.mouseleave();
hide();
}
});
$container.keypress(function (e) {
window.clearTimeout(to);
var c = String.fromCharCode(e.which);
pressed += c;
// We use JSON.stringify here to escape quotes
var $value = $innerblock.find('[data-value^='+JSON.stringify(pressed)+']:first');
if ($value.length) {
setActive($value);
$innerblock.scrollTop($value.position().top + $innerblock.scrollTop());
}
to = window.setTimeout(function () {
pressed = '';
}, 1000);
});
$container.setValue = function (val, name, sync) {
value = val;
// We use JSON.stringify here to escape quotes
@ -1741,6 +1713,85 @@ define([
};
}
var pressed = '';
var to;
var findItem = function () {
var $value = $();
$innerblock.find('[role="menuitem"]').each((i, el) => {
var $el = $(el);
var text = $el.text().toLowerCase();
var p = pressed.toLowerCase();
if (text.indexOf(p) === 0) {
$value = $el;
return false;
}
});
return $value;
};
$container.keydown(function (e) {
if (!$innerblock.is(':visible')) { return; }
var $value = $innerblock.find('li:focus');
if (!$value.length) {
$value = $innerblock.find('[role="menuitem"]').first();
}
if (e.which === 38) { // Up
e.preventDefault();
e.stopPropagation();
if ($value.length) {
$value.mouseleave();
var $prev = $value.prevAll('[role="menuitem"]:first');
$prev.mouseenter();
setFocus($prev);
}
}
if (e.which === 40) { // Down
e.preventDefault();
e.stopPropagation();
if ($value.length) {
$value.mouseleave();
var $next = $value.nextAll('[role="menuitem"]:first');
$next.mouseenter();
setFocus($next);
}
}
if (e.which === 13 || e.which === 32) { //Enter or space
e.preventDefault();
e.stopPropagation();
if ($value.length) {
$value.click();
hide();
$button.focus();
}
}
if (e.which === 27) { // Esc
e.preventDefault();
e.stopPropagation();
$value.mouseleave();
hide();
$button.focus();
}
});
$container.keypress(function (e) {
window.clearTimeout(to);
var c = String.fromCharCode(e.which);
pressed += c;
// We use JSON.stringify here to escape quotes
var $value;
if (config.isSelect) {
$value = $innerblock.find('[data-value^='+JSON.stringify(pressed)+']:first').closest('li');
} else {
$value = findItem();
}
if ($value.length) {
setFocus($value);
$innerblock.scrollTop($value.position().top + $innerblock.scrollTop());
}
to = window.setTimeout(function () {
pressed = '';
}, 1000);
});
return $container;
};
@ -1822,8 +1873,8 @@ define([
var options = [];
options.push({
tag: 'li',
attributes: {'class': 'cp-user-menu-logo', 'role': 'none'},
tag: 'div',
attributes: {'class': 'cp-user-menu-logo'},
content: h('span', [
h('img', {
src: '/customize/CryptPad_logo_grey.svg',
@ -1853,8 +1904,8 @@ define([
]));
}
options.push({
tag: 'li',
attributes: {'class': 'cp-toolbar-account', 'role': 'none'},
tag: 'div',
attributes: {'class': 'cp-toolbar-account'},
content: userAdminContent,
});
}
@ -1862,7 +1913,7 @@ define([
if (accountName && !AppConfig.disableProfile) {
options.push({
tag: 'a',
attributes: {'class': 'cp-toolbar-menu-profile fa fa-user-circle','tabindex': '-1','role':'menuitem'},
attributes: {'class': 'cp-toolbar-menu-profile fa fa-user-circle'},
content: h('span', Messages.profileButton),
action: function () {
if (padType) {
@ -1878,8 +1929,6 @@ define([
tag: 'a',
attributes: {
'class': 'fa fa-hdd-o',
'tabindex': '-1',
'role': 'menuitem'
},
content: h('span', Messages.type.drive),
action: function () {
@ -1892,8 +1941,6 @@ define([
tag: 'a',
attributes: {
'class': 'fa fa-users',
'tabindex': '-1',
'role': 'menuitem'
},
content: h('span', Messages.type.teams),
action: function () {
@ -1906,8 +1953,6 @@ define([
tag: 'a',
attributes: {
'class': 'fa fa-calendar',
'tabindex': '-1',
'role': 'menuitem'
},
content: h('span', Messages.calendar),
action: function () {
@ -1920,8 +1965,6 @@ define([
tag: 'a',
attributes: {
'class': 'fa fa-address-book',
'tabindex': '-1',
'role': 'menuitem'
},
content: h('span', Messages.type.contacts),
action: function () {
@ -1932,7 +1975,7 @@ define([
if (padType !== 'settings') {
options.push({
tag: 'a',
attributes: {'class': 'cp-toolbar-menu-settings fa fa-cog','tabindex': '-1','role':'menuitem'},
attributes: {'class': 'cp-toolbar-menu-settings fa fa-cog'},
content: h('span', Messages.settingsButton),
action: function () {
if (padType) {
@ -1949,7 +1992,7 @@ define([
if (priv.edPublic && Array.isArray(Config.adminKeys) && Config.adminKeys.indexOf(priv.edPublic) !== -1) {
options.push({
tag: 'a',
attributes: {'class': 'cp-toolbar-menu-admin fa fa-cogs','tabindex': '-1', 'role':'menuitem'},
attributes: {'class': 'cp-toolbar-menu-admin fa fa-cogs'},
content: h('span', Messages.adminPage || 'Admin'),
action: function () {
if (padType) {
@ -1967,8 +2010,6 @@ define([
'rel': 'noopener',
'href': 'https://docs.cryptpad.org',
'class': 'fa fa-book',
'role': 'menuitem',
'tabindex': -1
},
content: h('span', Messages.docs_link)
});
@ -1991,8 +2032,6 @@ define([
tag: 'a',
attributes: {
'class': 'cp-toolbar-about fa fa-info',
'tabindex': '-1',
'role': 'menuitem'
},
content: h('span', Messages.user_about),
action: function () {
@ -2004,8 +2043,6 @@ define([
tag: 'a',
attributes: {
'class': 'fa fa-home',
'tabindex': '-1',
'role': 'menuitem'
},
content: h('span', Messages.homePage),
action: function () {
@ -2047,8 +2084,6 @@ define([
tag: 'a',
attributes: {
'class': 'fa fa-gift',
'tabindex': '-1',
'role': 'menuitem'
},
content: h('span', Messages.crowdfunding_button2),
action: function () {
@ -2079,8 +2114,6 @@ define([
tag: 'a',
attributes: {
'class': 'cp-toolbar-menu-logout-everywhere fa fa-plug',
'tabindex': '-1',
'role': 'menuitem'
},
content: h('span', Messages.logoutEverywhere),
action: function () {
@ -2094,7 +2127,7 @@ define([
});
options.push({
tag: 'a',
attributes: {'class': 'cp-toolbar-menu-logout fa fa-sign-out','tabindex': '-1','role':'menuitem'},
attributes: {'class': 'cp-toolbar-menu-logout fa fa-sign-out'},
content: h('span', Messages.logoutButton),
action: function () {
Common.logout(function () {
@ -2105,7 +2138,7 @@ define([
} else {
options.push({
tag: 'a',
attributes: {'class': 'cp-toolbar-menu-login fa fa-sign-in','tabindex': '-1','role':'menuitem'},
attributes: {'class': 'cp-toolbar-menu-login fa fa-sign-in'},
content: h('span', Messages.login_login),
action: function () {
Common.setLoginRedirect('login');
@ -2114,7 +2147,7 @@ define([
if (!Config.restrictRegistration) {
options.push({
tag: 'a',
attributes: {'class': 'cp-toolbar-menu-register fa fa-user-plus','tabindex': '0', 'role':'menuitem'},
attributes: {'class': 'cp-toolbar-menu-register fa fa-user-plus'},
content: h('span', Messages.login_register),
action: function () {
Common.setLoginRedirect('register');
@ -2142,21 +2175,12 @@ define([
return true;
};
});
var liOptions = options.map(function (option) {
if (option.tag === 'li') {
return option;
}
return {
tag: 'li',
content: [option],
attributes: {'role': 'none'}
};
});
var dropdownConfigUser = {
buttonContent: $userButton[0],
options: liOptions, // Entries displayed in the menu
options: options, // Entries displayed in the menu
left: true, // Open to the left of the button
container: config.$initBlock, // optional
buttonTitle: config.buttonTitle,
feedback: "USER_ADMIN",
common: Common
};

View File

@ -3089,28 +3089,18 @@ define([
// Create dropdown
var options = getNewPadOptions(isInRoot).map(function (obj) {
if (obj.separator) {
return {
tag: 'li',
role: 'none',
content: {
tag: 'hr'
}
};
return { tag: 'hr', };
}
var newObj = {
tag: 'li',
attributes: { role: 'none'},
content: {
tag: 'a',
attributes: { 'class': obj.class, href: '#' },
content: [obj.icon, obj.name]
}
};
if (obj.type) {
newObj.content.attributes['data-type'] = obj.type;
newObj.content.attributes['href'] = APP.origin + Hash.hashToHref('', obj.type);
newObj.attributes['data-type'] = obj.type;
newObj.attributes['href'] = APP.origin + Hash.hashToHref('', obj.type);
}
return newObj;
@ -3132,69 +3122,10 @@ define([
// actions for +New menu button
var menuButton = $block.find('button');
menuButton.addClass('cp-app-drive-toolbar-new');
functionalDropdown(menuButton);
addNewPadHandlers($block, isInRoot);
$container.append($block);
};
var functionalDropdown = function ($button) {
$button.attr('aria-haspopup', 'menu');
$button.attr('aria-expanded', 'false');
$button.click(function () {
if ($button.attr('aria-expanded') === 'true') {
$button.attr('aria-expanded', 'false');
} else {
$button.attr('aria-expanded', 'true');
$(document).on('click', function (e) {
if (!$(e.target).closest(".cp-dropdown-content").length) {
$button.attr('aria-expanded', 'false');
$(document).off('keydown');
}
});
$button.blur();
const dropdownActive = $(".cp-dropdown-content");
if (dropdownActive.length > 0) {
setTimeout(function () {
let items = dropdownActive.find('li:visible');
const firstVisibleItem = items.filter(function () {
return !($(this).find('hr').length > 0);
}).first();
firstVisibleItem.attr('tabindex', '0').focus();
}, 0);
}
$(document).on('keydown', function (e) {
if (dropdownActive.is(":focus") || dropdownActive.find(':focus').length > 0) {
const items = dropdownActive.find('li:visible');
const focusedItem = items.filter(':focus');
items.attr('tabindex', '-1');
if (e.key === 'Tab') {
e.preventDefault();
} else if (e.key === 'ArrowUp' || e.key === 'ArrowDown') {
if (e.key === 'ArrowUp') {
var prevItem = focusedItem.prev().length ? focusedItem.prev() : items.last();
while (prevItem.find('hr').length > 0) {
prevItem = prevItem.prev().length ? prevItem.prev() : items.last();
}
prevItem.attr('tabindex', '0').focus();
} else if (e.key === 'ArrowDown') {
var nextItem = focusedItem.next().length ? focusedItem.next() : items.first();
while (nextItem.find('hr').length > 0) {
nextItem = nextItem.next().length ? nextItem.next() : items.first();
}
nextItem.attr('tabindex', '0').focus();
}
} else if (e.key === 'Escape') {
dropdownActive.find('li').attr('tabindex', '-1');
dropdownActive.attr('tabindex', '-1');
$(document).off('keydown');
$button.attr('aria-expanded', 'false');
$button.focus();
}
}
});
}
});
};
var createFilterButton = function (isTemplate, $container) {
if (!APP.loggedIn) { return; }
@ -3267,13 +3198,6 @@ define([
],
});
}
options = options.map(function (obj) {
return {
tag: 'li',
attributes: { role: 'none'},
content: obj
};
});
var dropdownConfig = {
buttonContent: [
h('i.fa.fa-filter'),
@ -3295,9 +3219,6 @@ define([
}
var $block = UIElements.createDropdown(dropdownConfig);
var menuButton = $block.find('button');
functionalDropdown(menuButton);
// Add style
if (APP.store[FILTER_BY]) {
$block.find('button').addClass('cp-toolbar-button-active');
@ -3391,6 +3312,7 @@ define([
h('i.fa.fa-minus'),
Messages.fm_type,
],
action: function (e) { onSortByClick.call($(e.target).find('a')[0]); }
},{
tag: 'a',
attributes: {'class': 'cp-app-drive-element-atime'},
@ -3398,6 +3320,7 @@ define([
h('i.fa.fa-minus'),
Messages.fm_lastAccess,
],
action: function (e) { onSortByClick.call($(e.target).find('a')[0]); }
},{
tag: 'a',
attributes: {'class': 'cp-app-drive-element-ctime'},
@ -3405,6 +3328,7 @@ define([
h('i.fa.fa-minus'),
Messages.fm_creation,
],
action: function (e) { onSortByClick.call($(e.target).find('a')[0]); }
}];
var dropdownConfig = {
text: '', // Button initial text
@ -3416,7 +3340,6 @@ define([
};
var $sortBlock = UIElements.createDropdown(dropdownConfig);
$sortBlock.find('button').append(h('span.fa.fa-sort-amount-desc')).append(h('span', Messages.fm_sort));
$sortBlock.on('click', 'a', onSortByClick);
return $fhSort;
};
var getFolderListHeader = function (clickable, small) {

View File

@ -753,6 +753,7 @@ define([
Util.fixFileName(suggestion), function (filename)
{
if (!(typeof(filename) === 'string' && filename)) { return; }
console.error(filename);
var ext = $select.getValue();
filename = filename + ext;
if (async) {

View File

@ -369,10 +369,10 @@ define([
$block.find('button').attr('title', Messages.languageButtonTitle);
var isHovering = false;
var $aLanguages = $block.find('a');
var $aLanguages = $block.find('li');
$aLanguages.mouseenter(function () {
isHovering = true;
setMode($(this).attr('data-value'));
setMode($(this).find('a').attr('data-value'));
});
$aLanguages.mouseleave(function () {
if (isHovering) {
@ -381,7 +381,7 @@ define([
});
$aLanguages.click(function () {
isHovering = false;
var mode = $(this).attr('data-value');
var mode = $(this).find('a').attr('data-value');
setMode(mode, onModeChanged);
onLocal();
});
@ -431,10 +431,10 @@ define([
setTheme(lastTheme, $block);
var isHovering = false;
var $aThemes = $block.find('a');
var $aThemes = $block.find('li');
$aThemes.mouseenter(function () {
isHovering = true;
var theme = $(this).attr('data-value');
var theme = $(this).find('a').attr('data-value');
setTheme(theme, $block);
});
$aThemes.mouseleave(function () {
@ -445,7 +445,7 @@ define([
});
$aThemes.click(function () {
isHovering = false;
var theme = $(this).attr('data-value');
var theme = $(this).find('a').attr('data-value');
setTheme(theme, $block);
Common.setAttribute(themeKey, theme);
});

View File

@ -1008,6 +1008,7 @@ MessengerUI, Messages, Pages) {
var $userAdmin = toolbar.$userAdmin.find('.'+USERADMIN_CLS).show();
var userMenuCfg = {
$initBlock: $userAdmin,
buttonTitle: Messages.userAccountButton,
};
if (!config.hideDisplayName) {
$.extend(true, userMenuCfg, {
@ -1020,101 +1021,6 @@ MessengerUI, Messages, Pages) {
userMenuCfg.displayChangeName = 1;
}
Common.createUserAdminMenu(userMenuCfg);
$userAdmin.find('> button').attr({
title: Messages.userAccountButton,
class: Messages.userAccountButton,
'aria-haspopup': 'menu',
'aria-expanded': 'false',
'aria-label': Messages.userAccountButton
});
function findItems(search, current, items) {
const currentIndex = items.index(current);
for (let i = 1; i < items.length; i++) {
const nextIndex = (currentIndex + i) % items.length;
const nextItem = items.eq(nextIndex);
const text = nextItem.text().trim().toLowerCase();
if (text.startsWith(search)) {
return nextItem;
}
}
return null;
}
let userMenuButton = $userAdmin.find('> button');
userMenuButton.click(function () {
const isExpanded = userMenuButton.attr('aria-expanded') === 'true';
if (isExpanded) {
userMenuButton.attr('aria-expanded', 'false');
$(document).off('keydown');
} else {
userMenuButton.attr('aria-expanded', 'true');
userMenuButton.blur();
const dropdownActive = $(".cp-dropdown-content");
if (dropdownActive.length > 0) {
setTimeout(function() {
let items = dropdownActive.find('li:visible');
const firstVisibleItem = items.filter(function () {
return !($(this).find('hr').length > 0 || $(this).hasClass('cp-user-menu-logo') || $(this).hasClass('cp-toolbar-account'));
}).first();
firstVisibleItem.attr('tabindex', '0').focus();
}, 0);
let searchCharacters = '';
document.addEventListener("visibilitychange", function () {
if (document.hidden) {
userMenuButton.attr('aria-expanded', 'false');
userMenuButton.focus();
$(document).off('keydown');
}
});
$(document).on('click', function (e) {
if ( !$(e.target).closest(".cp-dropdown-content").length) {
userMenuButton.attr('aria-expanded', 'false');
$(document).off('keydown');
}
});
$(document).on('keydown', function (e) {
if (dropdownActive.is(":focus") || dropdownActive.find(':focus').length > 0) {
const items = dropdownActive.find('li:visible');
const focusedItem = items.filter(':focus');
items.attr('tabindex', '-1');
if (e.key === 'Tab') {
e.preventDefault();
} else if (e.key === 'ArrowUp' || e.key === 'ArrowDown') {
if (e.key === 'ArrowUp') {
var prevItem = focusedItem.prev().length ? focusedItem.prev() : items.last();
while (prevItem.find('hr').length > 0 || prevItem.hasClass('cp-user-menu-logo') || prevItem.hasClass('cp-toolbar-account')) {
prevItem = prevItem.prev().length ? prevItem.prev() : items.last();
}
prevItem.attr('tabindex', '0').focus();
searchCharacters = '';
} else if (e.key === 'ArrowDown') {
var nextItem = focusedItem.next().length ? focusedItem.next() : items.first();
while (nextItem.find('hr').length > 0 || nextItem.hasClass('cp-user-menu-logo') || nextItem.hasClass('cp-toolbar-account')) {
nextItem = nextItem.next().length ? nextItem.next() : items.first();
}
nextItem.attr('tabindex', '0').focus();
searchCharacters = '';
}
}
else if (e.key === 'Escape') {
dropdownActive.find('li').attr('tabindex', '-1');
dropdownActive.attr('tabindex', '-1');
$(document).off('keydown');
userMenuButton.attr('aria-expanded', 'false');
userMenuButton.focus();
searchCharacters = '';
} else if (e.key.match(/[a-zA-Z]/)) {
searchCharacters += e.key.toLowerCase();
nextItem = findItems(searchCharacters, focusedItem, items);
if (nextItem) {
nextItem.attr('tabindex', '0').focus();
}
}
}
});
}
}
});
return $userAdmin;
};
@ -1168,50 +1074,59 @@ MessengerUI, Messages, Pages) {
var createNotifications = function (toolbar, config) {
var $notif = toolbar.$top.find('.'+NOTIFICATIONS_CLS).show();
var openNotifsApp = h('li', {}, h('div.cp-notifications-gotoapp', { tabindex: '0' }, h('p', Messages.openNotificationsApp || "Open notifications App")));
$(openNotifsApp).on('click keypress', function (event) {
if (event.type === 'click' || (event.type === 'keypress' && event.which === 13)) {
var options = [];
if (Common.isLoggedIn()) {
options.push({
tag: 'a',
attributes: { 'class':'cp-notifications-gotoapp' },
content: h('p', Messages.openNotificationsApp),
action: () => {
Common.openURL("/notifications/");
}
});
var div = h('ul.cp-notifications-container', [
h('div.cp-notifications-empty', Messages.notifications_empty)
]);
var pads_options = [div];
options.push({ tag: 'hr' });
}
var metadataMgr = config.metadataMgr;
var privateData = metadataMgr.getPrivateData();
if (!privateData.notifications) {
var allowNotif = h('div.cp-notifications-gotoapp', {tabindex: '0'}, h('p', Messages.allowNotifications));
allowNotif = h('li', {}, allowNotif);
pads_options.unshift(h("hr"));
pads_options.unshift(allowNotif);
$(allowNotif).on('click keypress', function (event) {
if (event.type === 'click' || (event.type === 'keypress' && event.which === 13)) {
Common.getSframeChannel().event('Q_ASK_NOTIFICATION', null, function (e, allow) {
options.push({
tag: 'a',
attributes: { 'class':'cp-notifications-gotoapp cp-notifications-allow' },
content: h('p', Messages.allowNotifications),
action: function (ev) {
Common.getSframeChannel().query('Q_ASK_NOTIFICATION', null, function (e, allow) {
console.error(e, allow);
if (!allow) { return; }
$(allowNotif).remove();
$(ev.target).closest('li').remove();
});
}
});
options.push({ tag: 'hr' });
var onChange = function () {
var privateData = metadataMgr.getPrivateData();
if (!privateData.notifications) { return; }
$allow.remove();
$('.cp-notifications-allow').closest('li').remove();
metadataMgr.off('change', onChange);
};
metadataMgr.onChange(onChange);
}
var div = h('ul.cp-notifications-container', [
h('li.cp-notifications-empty', Messages.notifications_empty)
]);
options.push({
tag: 'li',
content: div
});
if (Common.isLoggedIn()) {
pads_options.unshift(h("hr"));
pads_options.unshift(openNotifsApp);
}
var dropdownConfig = {
text: '', // Button initial text
options: pads_options, // Entries displayed in the menu
options: options, // Entries displayed in the menu
container: $notif,
left: true,
common: Common