diff --git a/edit.html b/edit.html index b162045a..8907cd5b 100644 --- a/edit.html +++ b/edit.html @@ -271,13 +271,16 @@
-
- +
+
+ +
- -
- -
diff --git a/edit/edit.css b/edit/edit.css index 0553f5bf..0ad6eec7 100644 --- a/edit/edit.css +++ b/edit/edit.css @@ -260,23 +260,13 @@ input:invalid { margin-top: .5rem; } -#actions > * { - display: inline-flex; - flex-wrap: wrap; -} - -#mozilla-format-buttons { +#actions .buttons { display: flex; flex-wrap: wrap; align-items: center; } -#actions > div > a { - height: min-content; -} - -#actions button, -#actions > div > a { +#actions .buttons > * { margin: 0 .2rem .5rem 0; } @@ -1065,11 +1055,7 @@ body.linter-disabled .hidden-unless-compact { padding: .25rem 0 .5rem; } #actions { - display: flex; - flex-wrap: wrap; white-space: nowrap; - margin: 0; - box-sizing: border-box; } #header input[type="checkbox"] { vertical-align: middle; diff --git a/edit/source-editor.js b/edit/source-editor.js index b9ce6c66..fb118b1c 100644 --- a/edit/source-editor.js +++ b/edit/source-editor.js @@ -23,7 +23,7 @@ function SourceEditor() { $('#header').on('wheel', headerOnScroll); $('#sections').textContent = ''; $('#sections').appendChild($create('.single-editor')); - $('[i18n-text="saveAsTemplate"]').onclick = saveTemplate; + $('#save-button').onauxclick = e => e.detail === 'tpl' && saveTemplate(); const cm = cmFactory.create($('.single-editor')); const sectionFinder = MozSectionFinder(cm); diff --git a/global.css b/global.css index 95440557..0f094b85 100644 --- a/global.css +++ b/global.css @@ -6,6 +6,7 @@ html#stylus #header *:not(#\1transition-suppressor) { } :root { --family: Arial, "Helvetica Neue", Helvetica, system-ui, sans-serif; + --bg: #fff; } body { font: normal 12px var(--family); @@ -33,6 +34,7 @@ button { border: 1px solid hsl(0, 0%, 62%); font: inherit; font-size: 13px; + line-height: 1.2; color: #000; background-color: hsl(0, 0%, 100%); background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAAeCAYAAADtlXTHAAAABmJLR0QA/wD/AP+gvaeTAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH4QwGBBwIHvKt6QAAAB1pVFh0Q29tbWVudAAAAAAAQ3JlYXRlZCB3aXRoIEdJTVBkLmUHAAAAL0lEQVQI12NoaGgQZ2JgYGBkYmBgYGZiYGBggrMY4VxsYsyoskQQCB2MWAxAMhkADVECDhlW9CoAAAAASUVORK5CYII='); @@ -307,6 +309,39 @@ body.resizing-v > * { } /* header resizer - end */ +.split-btn { + position: relative; +} +.split-btn-pedal { + margin-left: -1px !important; + padding-left: .2em !important; + padding-right: .2em !important; +} +.split-btn-pedal::after { + content: '\25BC'; /* down triangle */ + font-size: 90%; +} +.split-btn-pedal.active { + box-shadow: inset 0 0 100px rgba(0, 0, 0, .2); +} +.split-btn-menu { + background: #fff; + position: absolute; + box-shadow: 2px 3px 7px rgba(0, 0, 0, .5); + border: 1px solid hsl(180deg, 50%, 50%); + white-space: nowrap; + cursor: pointer; + padding: .25em 0; +} +.split-btn-menu > * { + padding: .5em 1em; + display: block; +} +.split-btn-menu > :hover { + background-color: hsla(180deg, 50%, 50%, .25); + color: #000; +} + @supports (-moz-appearance: none) { .moz-appearance-bug .svg-icon.checked, .moz-appearance-bug .onoffswitch input, diff --git a/js/dom-on-load.js b/js/dom-on-load.js index 828d14c8..634ae5dd 100644 --- a/js/dom-on-load.js +++ b/js/dom-on-load.js @@ -1,4 +1,4 @@ -/* global $ $$ focusAccessibility getEventKeyName */// dom.js +/* global $$ $ $create focusAccessibility getEventKeyName moveFocus */// dom.js /* global debounce */// toolbox.js /* global t */// localization.js 'use strict'; @@ -6,13 +6,14 @@ /** DOM housekeeping after a page finished loading */ (() => { + const SPLIT_BTN_MENU = '.split-btn-menu'; splitLongTooltips(); addTooltipsToEllipsized(); window.on('mousedown', suppressFocusRingOnClick, {passive: true}); window.on('keydown', keepFocusRingOnTabbing, {passive: true}); window.on('keypress', clickDummyLinkOnEnter); window.on('wheel', changeFocusedInputOnWheel, {capture: true, passive: false}); - window.on('click', showTooltipNote); + window.on('click', e => splitMenu(e) || showTooltipNote(e)); window.on('resize', () => debounce(addTooltipsToEllipsized, 100)); // Removing transition-suppressor rule const {sheet} = $('link[href$="global.css"]'); @@ -78,19 +79,44 @@ let el = document.activeElement; if (el) { el = el.closest('[data-focused-via-click]'); - if (el) delete el.dataset.focusedViaClick; + focusAccessibility.toggle(el, false); } }); } } + function splitMenu(event) { + const prevMenu = $(SPLIT_BTN_MENU); + const prevPedal = (prevMenu || {}).previousElementSibling; + const pedal = event.target.closest('.split-btn-pedal'); + const entry = prevMenu && event.target.closest(SPLIT_BTN_MENU + '>*'); + if (prevMenu) prevMenu.remove(); + if (prevPedal) prevPedal.classList.remove('active'); + if (pedal && pedal !== prevPedal) { + const menu = $create(SPLIT_BTN_MENU, + Array.from(pedal.attributes, ({name, value}) => + name.startsWith('menu-') && + $create('a', {tabIndex: 0, __cmd: name.split('-').pop()}, value) + )); + menu.on('focusout', e => e.target === menu && splitMenu(e)); + pedal.classList.toggle('active'); + pedal.after(menu); + moveFocus(menu, 0); + focusAccessibility.toggle(menu.firstChild, focusAccessibility.get(pedal)); + } + if (entry) { + prevPedal.previousElementSibling.dispatchEvent(new CustomEvent('auxclick', { + detail: entry.__cmd, + bubbles: true, + })); + } + } + function suppressFocusRingOnClick({target}) { const el = focusAccessibility.closest(target); if (el) { focusAccessibility.lastFocusedViaClick = true; - if (el.dataset.focusedViaClick === undefined) { - el.dataset.focusedViaClick = ''; - } + focusAccessibility.toggle(el, true); } } diff --git a/js/dom.js b/js/dom.js index 5cb50aeb..a650a387 100644 --- a/js/dom.js +++ b/js/dom.js @@ -31,6 +31,8 @@ Object.assign(EventTarget.prototype, { const focusAccessibility = { // last event's focusedViaClick lastFocusedViaClick: false, + get: el => el && el.dataset.focusedViaClick != null, + toggle: (el, state) => el && toggleDataset(el, 'focusedViaClick', state), // to avoid a full layout recalc due to changes on body/root // we modify the closest focusable element (like input or button or anything with tabindex=0) closest(el) {