mirror of https://github.com/xwiki-labs/cryptpad
Apply accessibility changes to all dropdowns
This commit is contained in:
parent
7fc3ff94a9
commit
31c3148580
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -867,7 +867,7 @@
|
|||
margin-left: 10px;
|
||||
}
|
||||
}
|
||||
li.cp-toolbar-account {
|
||||
div.cp-toolbar-account {
|
||||
&> span {
|
||||
font-weight: bold;
|
||||
span {
|
||||
|
|
|
@ -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); }
|
||||
|
|
|
@ -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 () {
|
||||
|
|
|
@ -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
|
||||
};
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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);
|
||||
});
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue