menus as dialogs (#727)
* menus as dialogs I think it's better in general, and also eliminates the glitchiness of expandable menus in FF, not to mention possible scroll issues on long style lists with overflow, plus the fact that we could add many menu items in the future without the menu looking ridiculous. IDEK how the formatting got screwed up and borked the diffs in the other PR. I updated my editor config plugin, so let's see if that helps. I restarted with a fresh master and copy/pasted the changes, so if it's still screwy, I guess my editor needs more help. If not, I'm not playing around with it anymore right now, and the other PR does at least work. * menus as dialogs
This commit is contained in:
parent
6fbc291b19
commit
bc56a7abd6
47
popup.html
47
popup.html
|
@ -47,33 +47,32 @@
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="menu">
|
<div class="menu" tabindex="-1">
|
||||||
<label class="menu-item exclude-by-domain button">
|
<div class="menu-items-wrapper">
|
||||||
<div class="menu-icon">
|
<b class="menu-title"></b>
|
||||||
<div class="checkbox-container">
|
<label class="menu-item exclude-by-domain button">
|
||||||
<input type="checkbox" class="exclude-by-domain-checkbox">
|
<div class="menu-icon">
|
||||||
<svg class="svg-icon checked"><use xlink:href="#svg-icon-checked"/></svg>
|
<div class="checkbox-container">
|
||||||
|
<input type="checkbox" class="exclude-by-domain-checkbox">
|
||||||
|
<svg class="svg-icon checked"><use xlink:href="#svg-icon-checked"/></svg>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
<span i18n-text="excludeStyleByDomainLabel"></span>
|
||||||
<span i18n-text="excludeStyleByDomainLabel"></span>
|
</label>
|
||||||
</label>
|
<label class="menu-item exclude-by-url button">
|
||||||
<label class="menu-item exclude-by-url button">
|
<div class="menu-icon">
|
||||||
<div class="menu-icon">
|
<div class="checkbox-container">
|
||||||
<div class="checkbox-container">
|
<input type="checkbox" class="exclude-by-url-checkbox">
|
||||||
<input type="checkbox" class="exclude-by-url-checkbox">
|
<svg class="svg-icon checked"><use xlink:href="#svg-icon-checked"/></svg>
|
||||||
<svg class="svg-icon checked"><use xlink:href="#svg-icon-checked"/></svg>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<span i18n-text="excludeStyleByUrlLabel"></span>
|
||||||
|
</label>
|
||||||
|
<div class="menu-buttons-wrapper">
|
||||||
|
<button class="delete" i18n-text="deleteStyleLabel"></button>
|
||||||
|
<button class="menu-close" i18n-text="confirmClose"></button>
|
||||||
</div>
|
</div>
|
||||||
<span i18n-text="excludeStyleByUrlLabel"></span>
|
</div>
|
||||||
</label>
|
|
||||||
<a href="#" class="menu-item delete">
|
|
||||||
<div class="menu-icon">
|
|
||||||
<svg class="svg-icon remove" viewBox="0 0 14 16">
|
|
||||||
<path fill-rule="evenodd" d="M11 2H9c0-.55-.45-1-1-1H5c-.55 0-1 .45-1 1H2c-.55 0-1 .45-1 1v1c0 .55.45 1 1 1v9c0 .55.45 1 1 1h7c.55 0 1-.45 1-1V5c.55 0 1-.45 1-1V3c0-.55-.45-1-1-1zm-1 12H3V5h1v8h1V5h1v8h1V5h1v8h1V5h1v9zm1-10H2V3h9v1z"/>
|
|
||||||
</svg>
|
|
||||||
</div>
|
|
||||||
<span i18n-text="deleteStyleLabel"></span>
|
|
||||||
</a>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
118
popup/popup.css
118
popup/popup.css
|
@ -26,10 +26,6 @@ body {
|
||||||
margin: 0;
|
margin: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
html, body:not(.search-results-shown) {
|
|
||||||
overflow: hidden;
|
|
||||||
}
|
|
||||||
|
|
||||||
.firefox body {
|
.firefox body {
|
||||||
color: #000;
|
color: #000;
|
||||||
background-color: #fff;
|
background-color: #fff;
|
||||||
|
@ -319,42 +315,60 @@ a.configure[target="_blank"] .svg-icon.config {
|
||||||
|
|
||||||
/* entry menu */
|
/* entry menu */
|
||||||
.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;
|
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;
|
border: none;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
padding: 3px 0 3px 20px;
|
padding: 3px 0;
|
||||||
background: none;
|
background: none;
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
flex: 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 {
|
.entry .menu-item > span {
|
||||||
margin-top: 1px;
|
margin: 1px 0 -1px;
|
||||||
}
|
}
|
||||||
.entry .menu-item:hover,
|
.entry .menu-item:hover,
|
||||||
.entry .menu-item:active {
|
.entry .menu-item:active {
|
||||||
|
@ -594,24 +608,54 @@ body.blocked .actions > .main-controls {
|
||||||
margin: 0 !important;
|
margin: 0 !important;
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
background-color: rgba(0, 0, 0, 0.4);
|
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: lights-on .25s ease-in-out;
|
||||||
animation-fill-mode: both;
|
animation-fill-mode: both;
|
||||||
}
|
}
|
||||||
|
|
||||||
#confirm.lights-on,
|
#confirm.lights-on,
|
||||||
#confirm.lights-on > div {
|
#confirm.lights-on > div,
|
||||||
|
.menu.lights-on > div {
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
#confirm[data-display=true] {
|
#confirm[data-display=true],
|
||||||
|
.menu[data-display=true] {
|
||||||
display: flex;
|
display: flex;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#confirm[data-display=true] + #installed .menu[data-display=true] {
|
||||||
|
opacity: 0;
|
||||||
|
pointer-events: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
#confirm > div {
|
||||||
|
width: 80%;
|
||||||
|
max-height: 80%;
|
||||||
|
min-height: 6em;
|
||||||
|
padding: 1em;
|
||||||
|
background-color: #fff;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
border: solid 2px rgba(0, 0, 0, 0.5);
|
||||||
|
}
|
||||||
|
|
||||||
|
#confirm > div > *:not(:last-child) {
|
||||||
|
padding-bottom: .5em;
|
||||||
|
}
|
||||||
|
|
||||||
|
#confirm > div > div {
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.non-windows #confirm > div > div {
|
||||||
|
direction: rtl;
|
||||||
|
text-align: right;
|
||||||
|
}
|
||||||
|
|
||||||
#confirm > div {
|
#confirm > div {
|
||||||
width: 80%;
|
width: 80%;
|
||||||
max-height: 80%;
|
max-height: 80%;
|
||||||
|
|
|
@ -311,6 +311,7 @@ function createStyleElement(style) {
|
||||||
$('.main-controls', entry).appendChild(indicator);
|
$('.main-controls', entry).appendChild(indicator);
|
||||||
|
|
||||||
$('.menu-button', entry).onclick = handleEvent.toggleMenu;
|
$('.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-domain-checkbox', entry).onchange = e => handleEvent.toggleExclude(e, 'domain');
|
||||||
$('.exclude-by-url-checkbox', entry).onchange = e => handleEvent.toggleExclude(e, 'url');
|
$('.exclude-by-url-checkbox', entry).onchange = e => handleEvent.toggleExclude(e, 'url');
|
||||||
|
@ -398,9 +399,37 @@ Object.assign(handleEvent, {
|
||||||
|
|
||||||
toggleMenu(event) {
|
toggleMenu(event) {
|
||||||
const entry = handleEvent.getClickedStyleElement(event);
|
const entry = handleEvent.getClickedStyleElement(event);
|
||||||
entry.classList.toggle('menu-active');
|
const menu = $('.menu', entry);
|
||||||
const menu = entry.querySelector('.menu');
|
const menuActive = $('.menu[data-display=true]');
|
||||||
menu.style.setProperty('--menu-height', menu.scrollHeight + 'px');
|
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();
|
event.preventDefault();
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -408,28 +437,55 @@ Object.assign(handleEvent, {
|
||||||
const entry = handleEvent.getClickedStyleElement(event);
|
const entry = handleEvent.getClickedStyleElement(event);
|
||||||
const id = entry.styleId;
|
const id = entry.styleId;
|
||||||
const box = $('#confirm');
|
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.dataset.display = true;
|
||||||
box.style.cssText = '';
|
box.style.cssText = '';
|
||||||
$('b', box).textContent = $('.style-name', entry).textContent;
|
$('b', box).textContent = $('.style-name', entry).textContent;
|
||||||
$('[data-cmd="ok"]', box).focus();
|
affirm.focus();
|
||||||
$('[data-cmd="ok"]', box).onclick = () => confirm(true);
|
affirm.onclick = () => confirm(true);
|
||||||
$('[data-cmd="cancel"]', box).onclick = () => confirm(false);
|
cancel.onclick = () => confirm(false);
|
||||||
window.onkeydown = event => {
|
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;
|
const keyCode = event.keyCode || event.which;
|
||||||
if (document.activeElement !== cancel && !event.shiftKey && !event.ctrlKey && !event.altKey && !event.metaKey
|
if (document.activeElement === cancel && (keyCode === 9)) {
|
||||||
&& (keyCode === 13 || keyCode === 27)) {
|
|
||||||
event.preventDefault();
|
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) {
|
function confirm(ok) {
|
||||||
window.onkeydown = null;
|
if (ok) {
|
||||||
animateElement(box, {
|
// fade-out deletion confirmation dialog
|
||||||
className: 'lights-on',
|
animateElement(box, {
|
||||||
onComplete: () => (box.dataset.display = false),
|
className: 'lights-on',
|
||||||
});
|
onComplete: () => (box.dataset.display = false),
|
||||||
if (ok) API.deleteStyle(id);
|
});
|
||||||
|
window.onkeydown = null;
|
||||||
|
API.deleteStyle(id);
|
||||||
|
} else {
|
||||||
|
box.dataset.display = false;
|
||||||
|
menu.focus();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user