From 517c32f8d237851713d596986b489f3095ae0e71 Mon Sep 17 00:00:00 2001 From: narcolepticinsomniac Date: Tue, 11 Jun 2019 12:41:52 -0400 Subject: [PATCH] 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. --- popup/popup.css | 118 +++++++++++++++++++++++++++++++++--------------- popup/popup.js | 88 +++++++++++++++++++++++++++++------- 2 files changed, 153 insertions(+), 53 deletions(-) diff --git a/popup/popup.css b/popup/popup.css index 490d0d8b..3191806e 100644 --- a/popup/popup.css +++ b/popup/popup.css @@ -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 { @@ -594,24 +608,54 @@ 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%; + 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 { width: 80%; max-height: 80%; diff --git a/popup/popup.js b/popup/popup.js index 0adc0337..86a871a0 100644 --- a/popup/popup.js +++ b/popup/popup.js @@ -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(); + } } },