menus mimic dialogs

This commit is contained in:
narcolepticinsomniac 2019-06-11 10:50:36 -04:00 committed by GitHub
parent 853ed217f8
commit 1e5383fc72
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 1484 additions and 1413 deletions

View File

@ -26,10 +26,6 @@ body {
margin: 0;
}
html, body:not(.search-results-shown) {
overflow: hidden;
}
.firefox body {
color: #000;
background-color: #fff;
@ -319,42 +315,60 @@ a.configure[target="_blank"] .svg-icon.config {
/* entry menu */
.entry .menu {
display: flex;
flex-direction: column;
top: 100%;
width: 100%;
z-index: 1;
box-sizing: border-box;
height: 0;
transition: height .25s ease-out, opacity .5s ease-in;
overflow: hidden;
opacity: 0;
}
.entry.menu-active .menu {
height: var(--menu-height, 0px);
opacity: 1;
}
/* accessibility */
.menu-item {
display: none;
position: fixed;
top: 0;
bottom: 0;
left: 0;
right: 0;
align-items: center;
justify-content: center;
z-index: 2147483647;
box-sizing: border-box;
overflow: hidden;
background-color: rgba(0, 0, 0, 0.4);
outline: none;
animation: lights-off .5s cubic-bezier(.03, .67, .08, .94);
animation-fill-mode: both;
}
.menu-title,
#confirm > div > b {
padding-bottom: .5em;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.menu-items-wrapper {
width: 80%;
max-height: 80%;
min-height: 6em;
padding: 1em;
display: flex;
position: relative;
flex-direction: column;
background-color: #fff;
border: solid 2px rgba(0, 0, 0, 0.5);
}
.menu-buttons-wrapper {
display: flex;
align-items: center;
justify-content: center;
padding: 1em 0 0;
}
.menu-buttons-wrapper button {
margin: 0 .25em;
}
.menu-item {
display: flex;
border: none;
align-items: center;
padding: 3px 0 3px 20px;
padding: 3px 0;
background: none;
text-decoration: none;
flex: none;
}
.entry.menu-active .menu-item {
display: flex;
}
.entry .menu-item.delete {
cursor: pointer;
}
.entry .menu-item.delete:hover {
color: #000;
}
.entry .menu-item > span {
margin-top: 1px;
margin: 1px 0 -1px;
}
.entry .menu-item:hover,
.entry .menu-item:active {
@ -369,11 +383,6 @@ a.configure[target="_blank"] .svg-icon.config {
display: block;
margin: 0 auto;
}
.entry .menu-item.disabled {
opacity: 0.5;
background-color: transparent;
cursor: help;
}
/* checkbox */
.checkbox-container {
@ -594,24 +603,30 @@ body.blocked .actions > .main-controls {
margin: 0 !important;
box-sizing: border-box;
background-color: rgba(0, 0, 0, 0.4);
animation: lights-off .5s cubic-bezier(.03, .67, .08, .94);
animation-fill-mode: both;
}
#confirm.lights-on {
#confirm.lights-on,
.menu.lights-on {
animation: lights-on .25s ease-in-out;
animation-fill-mode: both;
}
#confirm.lights-on,
#confirm.lights-on > div {
#confirm.lights-on > div,
.menu.lights-on > div {
display: none;
}
#confirm[data-display=true] {
#confirm[data-display=true],
.menu[data-display=true] {
display: flex;
}
#confirm[data-display=true] + #installed .menu[data-display=true] {
opacity: 0;
pointer-events: none;
}
#confirm > div {
width: 80%;
max-height: 80%;
@ -636,7 +651,7 @@ body.blocked .actions > .main-controls {
text-align: right;
}
#confirm > button {
#confirm > div > div button {
/* add a gap between buttons both for horizontal
or vertical (when the label is wide) layout */
margin: 0 .25em .25em 0;

View File

@ -311,6 +311,7 @@ function createStyleElement(style) {
$('.main-controls', entry).appendChild(indicator);
$('.menu-button', entry).onclick = handleEvent.toggleMenu;
$('.menu-close', entry).onclick = handleEvent.toggleMenu;
$('.exclude-by-domain-checkbox', entry).onchange = e => handleEvent.toggleExclude(e, 'domain');
$('.exclude-by-url-checkbox', entry).onchange = e => handleEvent.toggleExclude(e, 'url');
@ -398,9 +399,37 @@ Object.assign(handleEvent, {
toggleMenu(event) {
const entry = handleEvent.getClickedStyleElement(event);
entry.classList.toggle('menu-active');
const menu = entry.querySelector('.menu');
menu.style.setProperty('--menu-height', menu.scrollHeight + 'px');
const menu = $('.menu', entry);
const menuActive = $('.menu[data-display=true]');
if (menuActive) {
// fade-out style menu
animateElement(menu, {
className: 'lights-on',
onComplete: () => (menu.dataset.display = false),
});
window.onkeydown = null;
} else {
$('.menu-title', entry).textContent = $('.style-name', entry).textContent;
menu.dataset.display = true;
menu.style.cssText = '';
window.onkeydown = event => {
const close = $('.menu-close', entry);
const checkbox = $('.exclude-by-domain-checkbox', entry);
const keyCode = event.keyCode || event.which;
if (document.activeElement === close && (keyCode === 9) && !event.shiftKey) {
event.preventDefault();
checkbox.focus();
}
if (document.activeElement === checkbox && (keyCode === 9) && event.shiftKey) {
event.preventDefault();
close.focus();
}
if (keyCode === 27) {
event.preventDefault();
close.click();
}
};
}
event.preventDefault();
},
@ -408,28 +437,55 @@ Object.assign(handleEvent, {
const entry = handleEvent.getClickedStyleElement(event);
const id = entry.styleId;
const box = $('#confirm');
const cancel = $('[data-cmd="cancel"]');
const menu = $('.menu', entry);
const cancel = $('[data-cmd="cancel"]', box);
const affirm = $('[data-cmd="ok"]', box);
box.dataset.display = true;
box.style.cssText = '';
$('b', box).textContent = $('.style-name', entry).textContent;
$('[data-cmd="ok"]', box).focus();
$('[data-cmd="ok"]', box).onclick = () => confirm(true);
$('[data-cmd="cancel"]', box).onclick = () => confirm(false);
affirm.focus();
affirm.onclick = () => confirm(true);
cancel.onclick = () => confirm(false);
window.onkeydown = event => {
const close = $('.menu-close', entry);
const checkbox = $('.exclude-by-domain-checkbox', entry);
const confirmActive = $('#confirm[data-display="true"]');
const keyCode = event.keyCode || event.which;
if (document.activeElement !== cancel && !event.shiftKey && !event.ctrlKey && !event.altKey && !event.metaKey
&& (keyCode === 13 || keyCode === 27)) {
if (document.activeElement === cancel && (keyCode === 9)) {
event.preventDefault();
confirm(keyCode === 13);
affirm.focus();
}
if (document.activeElement === close && (keyCode === 9) && !event.shiftKey) {
event.preventDefault();
checkbox.focus();
}
if (document.activeElement === checkbox && (keyCode === 9) && event.shiftKey) {
event.preventDefault();
close.focus();
}
if (keyCode === 27) {
event.preventDefault();
if (confirmActive) {
box.dataset.display = false;
menu.focus();
} else {
close.click();
}
}
};
function confirm(ok) {
window.onkeydown = null;
animateElement(box, {
className: 'lights-on',
onComplete: () => (box.dataset.display = false),
});
if (ok) API.deleteStyle(id);
if (ok) {
// fade-out deletion confirmation dialog
animateElement(box, {
className: 'lights-on',
onComplete: () => (box.dataset.display = false),
});
window.onkeydown = null;
API.deleteStyle(id);
} else {
box.dataset.display = false;
menu.focus();
}
}
},