remove what-input, use own implementation, rebase on master

This commit is contained in:
tophf 2017-12-12 21:33:41 +03:00
parent 2cdd264780
commit fefe82fd54
25 changed files with 203 additions and 209 deletions

View File

@ -193,9 +193,7 @@
<svg class="svg-icon checked"><use xlink:href="#svg-icon-checked"/></svg> <svg class="svg-icon checked"><use xlink:href="#svg-icon-checked"/></svg>
</label> </label>
<a href="#" id="toggle-style-help" class="svg-inline-wrapper"> <a href="#" id="toggle-style-help" class="svg-inline-wrapper">
<svg class="svg-icon info"> <svg class="svg-icon info"><use xlink:href="#svg-icon-help"/></svg>
<use xlink:href="#svg-icon-help"/>
</svg>
</a> </a>
</div> </div>
</section> </section>
@ -203,10 +201,14 @@
<div> <div>
<button id="save-button" i18n-text="styleSaveLabel"></button> <button id="save-button" i18n-text="styleSaveLabel"></button>
<button id="beautify" i18n-text="styleBeautify"></button> <button id="beautify" i18n-text="styleBeautify"></button>
<a href="manage.html"><button id="cancel-button" i18n-text="styleCancelEditLabel" tabindex="-1"></button></a> <a href="manage.html" tabindex="-1"><button id="cancel-button" i18n-text="styleCancelEditLabel"></button></a>
</div> </div>
<div id="mozilla-format-container"> <div id="mozilla-format-container">
<h2 id="mozilla-format-heading" i18n-text="styleMozillaFormatHeading"><svg id="to-mozilla-help" class="svg-icon info"><use xlink:href="#svg-icon-help"/></svg></h2> <h2 id="mozilla-format-heading" i18n-text="styleMozillaFormatHeading">
<a class="svg-inline-wrapper" href="#">
<svg id="to-mozilla-help" class="svg-icon info"><use xlink:href="#svg-icon-help"/></svg>
</a>
</h2>
<button id="from-mozilla" i18n-text="importLabel"></button> <button id="from-mozilla" i18n-text="importLabel"></button>
<button id="to-mozilla" i18n-text="exportLabel"></button> <button id="to-mozilla" i18n-text="exportLabel"></button>
</div> </div>
@ -249,9 +251,7 @@
<svg class="svg-icon checked"><use xlink:href="#svg-icon-checked"/></svg> <svg class="svg-icon checked"><use xlink:href="#svg-icon-checked"/></svg>
</label> </label>
<a id="colorpicker-settings" href="#" class="svg-inline-wrapper" i18n-title="shortcutsNote"> <a id="colorpicker-settings" href="#" class="svg-inline-wrapper" i18n-title="shortcutsNote">
<svg class="svg-icon settings"> <svg class="svg-icon settings"><use xlink:href="#svg-icon-settings"/></svg>
<use xlink:href="#svg-icon-settings"/>
</svg>
</a> </a>
</div> </div>
<div class="option usercss-only"> <div class="option usercss-only">
@ -303,20 +303,17 @@
<svg class="svg-icon select-arrow"><use xlink:href="#svg-icon-select-arrow"/></svg> <svg class="svg-icon select-arrow"><use xlink:href="#svg-icon-select-arrow"/></svg>
</div> </div>
<a id="linter-settings" href="#" class="svg-inline-wrapper" i18n-title="linterConfigTooltip"> <a id="linter-settings" href="#" class="svg-inline-wrapper" i18n-title="linterConfigTooltip">
<svg class="svg-icon settings"> <svg class="svg-icon settings"><use xlink:href="#svg-icon-settings"/></svg>
<use xlink:href="#svg-icon-settings"/>
</svg>
</a> </a>
</div> </div>
</details> </details>
<details id="lint" class="hidden" data-pref="editor.lint.expanded"> <details id="lint" class="hidden" data-pref="editor.lint.expanded">
<summary> <summary>
<h2 i18n-text="linterIssues">: <span id="issue-count"></span></h2> <h2 i18n-text="linterIssues">: <span id="issue-count"></span>
<a id="lint-help" href="#" class="svg-inline-wrapper"> <a id="lint-help" href="#" class="svg-inline-wrapper intercepts-click">
<svg class="svg-icon info intercepts-click"> <svg class="svg-icon info"><use xlink:href="#svg-icon-help"/></svg>
<use xlink:href="#svg-icon-help"/> </a>
</svg> </h2>
</a>
</summary> </summary>
<div></div> <div></div>
</details> </details>
@ -327,7 +324,9 @@
</div> </div>
</div> </div>
<section id="sections"> <section id="sections">
<h2><span id="sections-heading" i18n-text="styleSectionsTitle"></span><svg id="sections-help" class="svg-icon info"><use xlink:href="#svg-icon-help"/></svg></h2> <h2><span id="sections-heading" i18n-text="styleSectionsTitle"></span>
<svg id="sections-help" class="svg-icon info"><use xlink:href="#svg-icon-help"/></svg>
</h2>
</section> </section>
<div id="help-popup"> <div id="help-popup">
<div class="title"></div><svg id="sections-help" class="svg-icon dismiss"><use xlink:href="#svg-icon-close"/></svg> <div class="title"></div><svg id="sections-help" class="svg-icon dismiss"><use xlink:href="#svg-icon-close"/></svg>
@ -362,6 +361,5 @@
</svg> </svg>
<script src="vendor/focus/what-input.min.js"></script>
</body> </body>
</html> </html>

View File

@ -62,7 +62,8 @@ onDOMscriptReady('/colorview.js').then(() => {
cm.state.colorpicker.openPopup(prefs.get('editor.colorpicker.color')); cm.state.colorpicker.openPopup(prefs.get('editor.colorpicker.color'));
} }
function configureColorpicker() { function configureColorpicker(event) {
event.preventDefault();
const input = $create('input', { const input = $create('input', {
type: 'search', type: 'search',
spellcheck: false, spellcheck: false,

View File

@ -76,19 +76,6 @@ label {
min-height: 1.4rem; min-height: 1.4rem;
} }
.svg-inline-wrapper {
outline: none;
text-decoration: none;
}
.svg-inline-wrapper svg {
border-bottom: 1px dashed transparent;
}
.svg-inline-wrapper:focus svg {
border-bottom-color: #AAA;
}
/* basic info */ /* basic info */
#basic-info { #basic-info {
margin-bottom: 1rem; margin-bottom: 1rem;
@ -106,21 +93,19 @@ label {
#url:not([href^="http"]) { #url:not([href^="http"]) {
display: none; display: none;
} }
#save-button {
opacity: .5;
pointer-events: none;
}
.dirty #save-button {
opacity: 1;
pointer-events: all;
}
.svg-icon { .svg-icon {
cursor: pointer; cursor: pointer;
vertical-align: middle; vertical-align: middle;
transition: fill .5s; transition: fill .5s;
width: 16px; width: 16px;
height: 16px; height: 16px;
margin-left: 0.2rem; }
.svg-inline-wrapper {
margin-left: .2rem;
display: inline-block;
}
.aligned .svg-inline-wrapper {
margin-left: .25rem;
} }
h2 .svg-icon, label .svg-icon { h2 .svg-icon, label .svg-icon {
margin-top: -1px; margin-top: -1px;
@ -619,6 +604,11 @@ html:not(.usercss) .usercss-only,
display: none !important; /* hide during page init */ display: none !important; /* hide during page init */
} }
.usercss #name {
background-color: #eee;
color: #888;
}
#sections .single-editor { #sections .single-editor {
margin: 0; margin: 0;
padding: 0; padding: 0;

View File

@ -273,8 +273,6 @@ function initHooks() {
} }
} }
// common for usercss and classic
function onChange(event) { function onChange(event) {
const node = event.target; const node = event.target;
if ('savedValue' in node) { if ('savedValue' in node) {
@ -317,12 +315,6 @@ function setCleanItem(node, isClean) {
function isCleanGlobal() { function isCleanGlobal() {
const clean = Object.keys(dirty).length === 0; const clean = Object.keys(dirty).length === 0;
setDirtyClass(document.body, !clean); setDirtyClass(document.body, !clean);
// let saveBtn = $('#save-button')
// if (clean){
// //saveBtn.removeAttribute('disabled');
// }else{
// //saveBtn.setAttribute('disabled', true);
// }
return clean; return clean;
} }
@ -406,6 +398,7 @@ function updateTitle() {
const clean = isCleanGlobal(); const clean = isCleanGlobal();
const title = styleId === null ? t('addStyleTitle') : t('editStyleTitle', [name]); const title = styleId === null ? t('addStyleTitle') : t('editStyleTitle', [name]);
document.title = clean ? title : DIRTY_TITLE.replace('$', title); document.title = clean ? title : DIRTY_TITLE.replace('$', title);
$('#save-button').disabled = clean;
} }
function updateLintReportIfEnabled(...args) { function updateLintReportIfEnabled(...args) {
@ -500,15 +493,18 @@ function fromMozillaFormat() {
} }
} }
function showSectionHelp() { function showSectionHelp(event) {
event.preventDefault();
showHelp(t('styleSectionsTitle'), t('sectionHelp')); showHelp(t('styleSectionsTitle'), t('sectionHelp'));
} }
function showAppliesToHelp() { function showAppliesToHelp(event) {
event.preventDefault();
showHelp(t('appliesLabel'), t('appliesHelp')); showHelp(t('appliesLabel'), t('appliesHelp'));
} }
function showToMozillaHelp() { function showToMozillaHelp(event) {
event.preventDefault();
showHelp(t('styleMozillaFormatHeading'), t('styleToMozillaFormatHelp')); showHelp(t('styleMozillaFormatHeading'), t('styleToMozillaFormatHelp'));
} }

View File

@ -149,7 +149,8 @@ var linterConfig = {
}, },
// this is an event listener so it can't refer to self via 'this' // this is an event listener so it can't refer to self via 'this'
openOnClick() { openOnClick(event) {
event.preventDefault();
setupLinterPopup(linterConfig.stringify()); setupLinterPopup(linterConfig.stringify());
}, },

View File

@ -1,13 +1,3 @@
html:not([data-whatinput="keyboard"]) button,
html:not([data-whatinput="keyboard"]) input[type="checkbox"],
html:not([data-whatinput="keyboard"]) input[type="radio"],
html:not([data-whatinput="keyboard"]) #header summary,
html:not([data-whatinput="keyboard"]) .applies-to-extra-expander,
html:not([data-whatinput="keyboard"]) .regexp-report summary,
html:not([data-whatinput="keyboard"]) .regexp-report div {
outline: none;
}
button { button {
-webkit-appearance: none; -webkit-appearance: none;
-moz-appearance: none; -moz-appearance: none;
@ -17,7 +7,8 @@ button {
font: 400 13.3333px Arial; font: 400 13.3333px Arial;
color: #000; color: #000;
background-color: hsl(0, 0%, 100%); background-color: hsl(0, 0%, 100%);
background: url(../images/button.png)repeat-x; background: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAAeCAYAAADtlXTHAAAABmJLR0QA/wD/AP+gvaeTAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH4QwGBBwIHvKt6QAAAB1pVFh0Q29tbWVudAAAAAAAQ3JlYXRlZCB3aXRoIEdJTVBkLmUHAAAAL0lEQVQI12NoaGgQZ2JgYGBkYmBgYGZiYGBggrMY4VxsYsyoskQQCB2MWAxAMhkADVECDhlW9CoAAAAASUVORK5CYII=');
background-repeat: repeat-x;
background-size: 100% 100%; background-size: 100% 100%;
transition: background-color .25s, border-color .25s; transition: background-color .25s, border-color .25s;
} }
@ -30,7 +21,8 @@ button:not(:disabled):hover {
button:active { button:active {
background-color: hsl(0, 0%, 95%); background-color: hsl(0, 0%, 95%);
border-color: hsl(0, 0%, 52%); border-color: hsl(0, 0%, 52%);
background: url(../images/button-active.png)repeat-x; background: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAAeCAYAAADtlXTHAAAABmJLR0QA/wD/AP+gvaeTAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH4QwJARIWJNZvuQAAAB1pVFh0Q29tbWVudAAAAAAAQ3JlYXRlZCB3aXRoIEdJTVBkLmUHAAAAMElEQVQI12NoaGgIZmJgYPjLxMDA8I+JgYHhP5z1Dy7xH5X7jxQCzWQ0A9DEILYBABm5HtJk2jPHAAAAAElFTkSuQmCC');
background-repeat: repeat-x;
background-size: 100% 100%; background-size: 100% 100%;
} }
@ -185,6 +177,11 @@ select[disabled] > option {
display: none !important; display: none !important;
} }
[data-focused-via-click] :focus,
[data-focused-via-click]:focus {
outline: none;
}
@supports (-moz-appearance: none) { @supports (-moz-appearance: none) {
.moz-appearance-bug .svg-icon.checked, .moz-appearance-bug .svg-icon.checked,
.moz-appearance-bug .onoffswitch input, .moz-appearance-bug .onoffswitch input,

Binary file not shown.

Before

Width:  |  Height:  |  Size: 204 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 203 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 532 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.5 KiB

View File

@ -91,7 +91,6 @@
</div> </div>
</div> </div>
<script src="vendor/focus/what-input.min.js"></script>
<script src="/install-usercss/install-usercss.js"></script> <script src="/install-usercss/install-usercss.js"></script>
<svg xmlns="http://www.w3.org/2000/svg" style="display: none !important;"> <svg xmlns="http://www.w3.org/2000/svg" style="display: none !important;">

View File

@ -57,6 +57,7 @@ $$.remove = (selector, base = document) => {
onDOMready().then(() => { onDOMready().then(() => {
$.remove('#firefox-transitions-bug-suppressor'); $.remove('#firefox-transitions-bug-suppressor');
initCollapsibles(); initCollapsibles();
focusAccessibility();
}); });
if (!chrome.app && chrome.windows) { if (!chrome.app && chrome.windows) {
@ -314,3 +315,46 @@ function initCollapsibles({bindClickOn = 'h2'} = {}) {
prefs.set(el.dataset.pref, el.open); prefs.set(el.dataset.pref, el.open);
} }
} }
function focusAccessibility() {
// Makes the focus outline appear on keyboard tabbing, but not on mouse clicks.
// Since we don't want full layout recalc, we modify only the closest focusable element,
// which we try to find in DOM for this many parentElement jumps:
const focusables = focusAccessibility.ELEMENTS =
['a', 'button', 'input', 'label', 'select', 'summary'];
const GIVE_UP_DEPTH = 4;
addEventListener('mousedown', suppressOutlineOnClick, {passive: true});
addEventListener('keydown', keepOutlineOnTab, {passive: true});
function suppressOutlineOnClick({target}) {
for (let el = target, i = 0; el && i++ < GIVE_UP_DEPTH; el = el.parentElement) {
if (focusables.includes(el.localName)) {
if (el.dataset.focusedViaClick === undefined) {
el.dataset.focusedViaClick = '';
}
return;
}
}
}
function keepOutlineOnTab(event) {
if (event.which === 9) {
setTimeout(keepOutlineOnTab, 0, true);
return;
} else if (event !== true) {
return;
}
let el = document.activeElement;
if (!el || !focusables.includes(el.localName)) {
return;
}
if (el.dataset.focusedViaClick !== undefined) {
delete el.dataset.focusedViaClick;
}
el = el.closest('[data-focused-via-click]');
if (el) {
delete el.dataset.focusedViaClick;
}
}
}

View File

@ -166,11 +166,13 @@
<details id="filters" data-pref="manage.filters.expanded"> <details id="filters" data-pref="manage.filters.expanded">
<summary> <summary>
<h2 i18n-text="manageFilters">: <span id="filters-stats"></span></h2> <h2 i18n-text="manageFilters">: <span id="filters-stats"></span></h2>
<svg id="reset-filters" class="svg-icon" viewBox="0 0 20 20"> <a id="reset-filters" href="#">
<title i18n-text="genericResetLabel"></title> <svg class="svg-icon" viewBox="0 0 20 20">
<polygon points="16.2,5.5 14.5,3.8 10,8.3 5.5,3.8 3.8,5.5 8.3,10 3.8,14.5 <title i18n-text="genericResetLabel"></title>
5.5,16.2 10,11.7 14.5,16.2 16.2,14.5 11.7,10 "/> <polygon points="16.2,5.5 14.5,3.8 10,8.3 5.5,3.8 3.8,5.5 8.3,10 3.8,14.5
</svg> 5.5,16.2 10,11.7 14.5,16.2 16.2,14.5 11.7,10 "/>
</svg>
</a>
</summary> </summary>
<div class="filter-selection"> <div class="filter-selection">
@ -341,7 +343,6 @@
<div id="installed"></div> <div id="installed"></div>
<script src="vendor/focus/what-input.min.js"></script>
<script src="manage/import-export.js"></script> <script src="manage/import-export.js"></script>
<script src="msgbox/msgbox.js"></script> <script src="msgbox/msgbox.js"></script>
<script src="manage/incremental-search.js" async></script> <script src="manage/incremental-search.js" async></script>

View File

@ -93,20 +93,12 @@
margin-right: 4px; margin-right: 4px;
} }
.config-reset-icon { .config-body label:not(.nondefault) .config-reset-icon {
width: 16px; visibility: hidden;
display: inline-block;
}
.config-body label:not(.nondefault) .config-reset-icon a {
display: none;
} }
.config-reset-icon .svg-icon { .config-reset-icon .svg-icon {
/*position: absolute;*/
pointer-events: none;
cursor: pointer; cursor: pointer;
/*right: -7px;*/
fill: #aaa; fill: #aaa;
width: 16px; width: 16px;
height: 16px; height: 16px;

View File

@ -30,13 +30,13 @@ function configDialog(style) {
], ],
buttons: [{ buttons: [{
textContent: t('confirmSave'), textContent: t('confirmSave'),
dataset: {cmd: 'save', allowEnter: true}, dataset: {cmd: 'save'},
disabled: true, disabled: true,
onclick: save, onclick: save,
}, { }, {
textContent: t('genericResetLabel'), textContent: t('genericResetLabel'),
title: t('optionsReset'), title: t('optionsReset'),
dataset: {cmd: 'default', allowEnter: true}, dataset: {cmd: 'default'},
onclick: useDefault, onclick: useDefault,
}, { }, {
textContent: t('confirmClose'), textContent: t('confirmClose'),
@ -78,13 +78,7 @@ function configDialog(style) {
updateButtons(); updateButtons();
} }
function onhide({button, enter}) { function onhide() {
if (enter) {
switch (button) {
case 0: save(); break;
case 1: useDefault(); break;
}
}
document.body.style.minWidth = ''; document.body.style.minWidth = '';
document.body.style.minHeight = ''; document.body.style.minHeight = '';
colorpicker.hide(); colorpicker.hide();
@ -201,8 +195,8 @@ function configDialog(style) {
} }
function buildConfigForm() { function buildConfigForm() {
let resetter = $create('span.config-reset-icon', [ let resetter =
$create('a', {href:'#', dataset: {allowEnter: true}}, [ $create('a.config-reset-icon', {href: '#'}, [
$create('SVG:svg.svg-icon', {viewBox: '0 0 20 20'}, [ $create('SVG:svg.svg-icon', {viewBox: '0 0 20 20'}, [
$create('SVG:title', t('genericResetLabel')), $create('SVG:title', t('genericResetLabel')),
$create('SVG:polygon', { $create('SVG:polygon', {
@ -210,8 +204,7 @@ function configDialog(style) {
'5.5,16.2 10,11.7 14.5,16.2 16.2,14.5 11.7,10', '5.5,16.2 10,11.7 14.5,16.2 16.2,14.5 11.7,10',
}) })
]) ])
]) ]);
]);
for (const va of vars) { for (const va of vars) {
let children; let children;
switch (va.type) { switch (va.type) {
@ -221,7 +214,6 @@ function configDialog(style) {
va.input = $create('a.color-swatch', { va.input = $create('a.color-swatch', {
va, va,
href: '#', href: '#',
dataset: {allowEnter: true},
onclick: showColorpicker onclick: showColorpicker
}), }),
]), ]),
@ -272,8 +264,8 @@ function configDialog(style) {
} }
resetter = resetter.cloneNode(true); resetter = resetter.cloneNode(true);
$('a', resetter).va = va; resetter.va = va;
$('a', resetter).onclick = resetOnClick; resetter.onclick = resetOnClick;
elements.push( elements.push(
$create(`label.config-${va.type}`, [ $create(`label.config-${va.type}`, [
@ -281,6 +273,8 @@ function configDialog(style) {
...children, ...children,
resetter, resetter,
])); ]));
va.savedValue = va.value;
} }
} }
@ -319,22 +313,18 @@ function configDialog(style) {
const el = va.input.closest('label'); const el = va.input.closest('label');
el.classList.toggle('dirty', Boolean(va.dirty)); el.classList.toggle('dirty', Boolean(va.dirty));
el.classList.toggle('nondefault', !isDefault(va)); el.classList.toggle('nondefault', !isDefault(va));
$('.config-reset-icon', el).disabled = isDefault(va);
} }
function resetOnClick(event) { function resetOnClick(event) {
if ( event.preventDefault();
event.type === 'click' || this.va.value = null;
(event.keyCode || event.which) === 13 renderValues([this.va]);
) { onchange({target: this.va.input});
event.preventDefault();
event.stopPropagation();
this.va.value = null;
renderValues([this.va]);
onchange({target: this.va.input});
}
} }
function showColorpicker() { function showColorpicker(event) {
event.preventDefault();
window.removeEventListener('keydown', messageBox.listeners.key, true); window.removeEventListener('keydown', messageBox.listeners.key, true);
const box = $('#message-box-contents'); const box = $('#message-box-contents');
colorpicker.show({ colorpicker.show({

View File

@ -353,7 +353,9 @@ function showFiltersStats() {
debounce(showFiltersStats, 100); debounce(showFiltersStats, 100);
return; return;
} }
$('#filters summary').classList.toggle('active', filtersSelector.hide !== ''); const active = filtersSelector.hide !== '';
$('#filters summary').classList.toggle('active', active);
$('#reset-filters').disabled = !active;
const numTotal = BG.cachedStyles.list.length; const numTotal = BG.cachedStyles.list.length;
const numHidden = installed.getElementsByClassName('entry hidden').length; const numHidden = installed.getElementsByClassName('entry hidden').length;
const numShown = Math.min(numTotal - numHidden, installed.children.length); const numShown = Math.min(numTotal - numHidden, installed.children.length);

View File

@ -145,12 +145,11 @@ select {
} }
.svg-icon.config { .svg-icon.config {
width: 16px; transform: scale(.8);
height: 16px;
} }
.homepage { .homepage {
margin-left: 0.1em; margin-left: 0.25em;
margin-right: 0.1em; margin-right: 0.1em;
} }
@ -160,7 +159,6 @@ select {
.homepage .svg-icon { .homepage .svg-icon {
margin-top: 0; margin-top: 0;
margin-left: .5ex;
} }
.style-name { .style-name {
@ -190,6 +188,7 @@ select {
.actions > * { .actions > * {
margin-bottom: .25rem; margin-bottom: .25rem;
display: inline-block;
} }
.actions > *:not(:last-child) { .actions > *:not(:last-child) {
@ -450,11 +449,9 @@ select {
color: hsla(180, 100%, 15%, 1); color: hsla(180, 100%, 15%, 1);
} }
/* align delete button if no homepage link */ .newUI .homepage:not([href=""]) {
.newUI a.homepage.disabled { position: absolute;
/* margin-left: 0.5ex + 20px svg width + margin-right: 8px */ margin-left: -28px;
width: calc(0.5ex + 28px);
display: inline-block;
} }
.newUI .actions { .newUI .actions {
@ -464,30 +461,9 @@ select {
} }
.newUI .actions > * { .newUI .actions > * {
margin: 0; margin: 0 8px 0 0;
} width: 20px;
height: 20px;
.newUI .actions .svg-icon {
margin-right: 8px;
}
.newUI .style-name-link:focus,
.newUI .actions a:focus,
.newUI a.expander {
outline: none;
text-decoration: none;
}
.newUI .style-name-link,
.newUI .actions a svg,
.newUI a.expander {
border-bottom: 1px dashed transparent;
}
.newUI .style-name-link:focus,
.newUI .actions a:focus svg,
.newUI a.expander:focus {
border-bottom: 1px dashed #AAA;
} }
.newUI .updater-icons > * { .newUI .updater-icons > * {
@ -509,7 +485,7 @@ select {
.newUI .checking-update .check-update { .newUI .checking-update .check-update {
opacity: 0; opacity: 0;
display: inline; display: inline-block;
pointer-events: none; pointer-events: none;
} }
@ -517,7 +493,7 @@ select {
.newUI .no-update:not(.update-problem):not(.update-done) .up-to-date, .newUI .no-update:not(.update-problem):not(.update-done) .up-to-date,
.newUI .no-update.update-problem .check-update, .newUI .no-update.update-problem .check-update,
.newUI .update-done .updated { .newUI .update-done .updated {
display: inline; display: inline-block;
} }
.newUI .up-to-date svg, .newUI .up-to-date svg,
@ -623,7 +599,7 @@ select {
} }
.newUI .has-favicons .applies-to .expander { .newUI .has-favicons .applies-to .expander {
padding-left: 20px; margin-left: 20px;
} }
.newUI .target:hover { .newUI .target:hover {
@ -682,8 +658,7 @@ select {
margin-right: .5em; margin-right: .5em;
} }
#newUIoptions [data-toggle-on-click], #newUIoptions [data-toggle-on-click] svg {
#newUIoptions a[data-toggle-on-click] svg {
transform: rotate(-90deg); transform: rotate(-90deg);
cursor: pointer; cursor: pointer;
right: -16px; right: -16px;
@ -691,8 +666,7 @@ select {
pointer-events: auto; pointer-events: auto;
} }
#newUIoptions [data-toggle-on-click][open], #newUIoptions [data-toggle-on-click][open] svg {
#newUIoptions a[data-toggle-on-click][open] svg {
transform: none; transform: none;
} }
@ -720,7 +694,7 @@ input[id^="manage.newUI"] {
/* Check update button for things that can */ /* Check update button for things that can */
.updatable .check-update { .updatable .check-update {
display: inline; display: inline-block;
} }
/* Update check in progress */ /* Update check in progress */
@ -730,7 +704,7 @@ input[id^="manage.newUI"] {
/* Updates available */ /* Updates available */
.can-update .update { .can-update .update {
display: inline; display: inline-block;
} }
.can-update[data-details$="locally edited"] button.update:after { .can-update[data-details$="locally edited"] button.update:after {
@ -827,6 +801,10 @@ input[id^="manage.newUI"] {
#reset-filters { #reset-filters {
position: absolute; position: absolute;
margin-top: 2px; margin-top: 2px;
display: inline-block;
}
#reset-filters svg {
fill: hsla(180, 50%, 27%, .5); fill: hsla(180, 50%, 27%, .5);
width: 24px; /* widen the click area a bit */ width: 24px; /* widen the click area a bit */
height: 20px; height: 20px;
@ -834,7 +812,7 @@ input[id^="manage.newUI"] {
box-sizing: border-box; box-sizing: border-box;
} }
#reset-filters:hover { #reset-filters:hover svg {
fill: hsla(180, 50%, 27%, 1); fill: hsla(180, 50%, 27%, 1);
} }
@ -862,7 +840,7 @@ input[id^="manage.newUI"] {
border-radius: 0.25rem; border-radius: 0.25rem;
} }
#search-wrapper #search-help { #search-help {
margin: 4px 0 0 8px; margin: 4px 0 0 8px;
} }

View File

@ -191,9 +191,6 @@ function createStyleElement({style, name}) {
if (style.url) { if (style.url) {
$('.homepage', entry).appendChild(parts.homepageIcon.cloneNode(true)); $('.homepage', entry).appendChild(parts.homepageIcon.cloneNode(true));
} else {
$('.homepage', entry).removeAttribute('href');
$('.homepage', entry).classList.add('disabled');
} }
if (style.updateUrl && newUI.enabled) { if (style.updateUrl && newUI.enabled) {
$('.actions', entry).appendChild(template.updaterIcons.cloneNode(true)); $('.actions', entry).appendChild(template.updaterIcons.cloneNode(true));
@ -395,6 +392,7 @@ Object.assign(handleEvent, {
}, },
config(event, {styleMeta}) { config(event, {styleMeta}) {
event.preventDefault()
configDialog(styleMeta); configDialog(styleMeta);
}, },
}); });

View File

@ -180,15 +180,17 @@ function showUpdateHistory(event) {
messageBox({ messageBox({
title: t('updateCheckHistory'), title: t('updateCheckHistory'),
contents: log, contents: log,
blockScroll: true,
buttons: [ buttons: [
t('confirmOK'), t('confirmOK'),
logText && {textContent: t('confirmDelete'), onclick: deleteHistory}, logText && {textContent: t('confirmDelete'), onclick: deleteHistory},
], ],
onshow: logText && (() => { onshow: logText && (() => {
scroller = $('#message-box-contents'); scroller = $('#message-box-contents');
scroller.setAttribute('tabindex', 0); scroller.tabIndex = 0;
scroller.focus(); setTimeout(() => scroller.focus());
scrollToBottom(); scrollToBottom();
$('#message-box-buttons button').insertAdjacentElement('afterend', $('#message-box-buttons button').insertAdjacentElement('afterend',
// TODO: add a global class for our labels // TODO: add a global class for our labels
// TODO: add a <template> or a common function to create such controls // TODO: add a <template> or a common function to create such controls
@ -199,9 +201,9 @@ function showUpdateHistory(event) {
$create('SVG:use', {'xlink:href': '#svg-icon-checked'})), $create('SVG:use', {'xlink:href': '#svg-icon-checked'})),
t('manageOnlyUpdates'), t('manageOnlyUpdates'),
])); ]));
toggler.onchange(); toggler.onchange();
}), }),
blockScroll: true
}); });
}); });
function scrollToBottom() { function scrollToBottom() {

View File

@ -1,3 +1,4 @@
/* global focusAccessibility */
'use strict'; 'use strict';
function messageBox({ function messageBox({
@ -8,20 +9,18 @@ function messageBox({
onshow, // function(messageboxElement) invoked after the messagebox is shown onshow, // function(messageboxElement) invoked after the messagebox is shown
blockScroll, // boolean, blocks the page scroll blockScroll, // boolean, blocks the page scroll
}) { // RETURNS: Promise resolved to {button[number], enter[boolean], esc[boolean]} }) { // RETURNS: Promise resolved to {button[number], enter[boolean], esc[boolean]}
messageBox.originalFocus = document.activeElement;
initOwnListeners(); initOwnListeners();
bindGlobalListeners(); bindGlobalListeners();
createElement(); createElement();
document.body.appendChild(messageBox.element); document.body.appendChild(messageBox.element);
if (onshow) {
messageBox.originalFocus = document.activeElement;
moveFocus(1);
if (typeof onshow === 'function') {
onshow(messageBox.element); onshow(messageBox.element);
} }
messageBox.element.focus();
const firstEl = $('a, button, input, select', messageBox.element);
if (firstEl) {
firstEl.focus();
}
messageBox.lastEl = firstEl || messageBox.element;
return new Promise(_resolve => { return new Promise(_resolve => {
messageBox.resolve = _resolve; messageBox.resolve = _resolve;
}); });
@ -35,28 +34,30 @@ function messageBox({
resolveWith({button: this.buttonIndex}); resolveWith({button: this.buttonIndex});
}, },
key(event) { key(event) {
const keyCode = event.keyCode || event.which; const {which, shiftKey, ctrlKey, altKey, metaKey, target} = event;
if (event.target.closest('#message-box, .colorpicker-popup')) { if (shiftKey && which !== 9 || ctrlKey || altKey || metaKey) {
messageBox.lastEl = event.target;
}
if (keyCode === 13 && event.target.dataset.allowEnter) {
// usercss item resets needs to activate
return; return;
} }
if (!event.shiftKey && !event.ctrlKey && !event.altKey && !event.metaKey switch (which) {
&& (keyCode === 13 || keyCode === 27)) { case 13:
event.preventDefault(); for (let el = target; el; el = el.parentElement) {
event.stopPropagation(); if (focusAccessibility.ELEMENTS.includes(el.localName)) {
resolveWith(keyCode === 13 ? {enter: true, button: event.target.buttonIndex} : {esc: true}); return;
} }
}, }
keyup(event) { break;
const keyCode = event.keyCode || event.which; case 27:
if (keyCode === 9 && !event.target.closest('#message-box, .colorpicker-popup')) { event.preventDefault();
event.preventDefault(); event.stopPropagation();
event.stopPropagation(); break;
messageBox.lastEl.focus(); case 9:
moveFocus(shiftKey ? -1 : 1);
event.preventDefault();
return;
default:
return;
} }
resolveWith(which === 13 ? {enter: true} : {esc: true});
}, },
scroll() { scroll() {
scrollTo(blockScroll.x, blockScroll.y); scrollTo(blockScroll.x, blockScroll.y);
@ -71,7 +72,9 @@ function messageBox({
className: 'fadeout', className: 'fadeout',
onComplete: removeSelf, onComplete: removeSelf,
}); });
messageBox.originalFocus.focus(); if (messageBox.element.contains(document.activeElement)) {
messageBox.originalFocus.focus();
}
} }
function createElement() { function createElement() {
@ -107,12 +110,10 @@ function messageBox({
window.addEventListener('scroll', messageBox.listeners.scroll); window.addEventListener('scroll', messageBox.listeners.scroll);
} }
window.addEventListener('keydown', messageBox.listeners.key, true); window.addEventListener('keydown', messageBox.listeners.key, true);
window.addEventListener('keyup', messageBox.listeners.keyup, true);
} }
function unbindGlobalListeners() { function unbindGlobalListeners() {
window.removeEventListener('keydown', messageBox.listeners.key, true); window.removeEventListener('keydown', messageBox.listeners.key, true);
window.removeEventListener('keyup', messageBox.listeners.keyup, true);
window.removeEventListener('scroll', messageBox.listeners.scroll); window.removeEventListener('scroll', messageBox.listeners.scroll);
} }
@ -121,6 +122,21 @@ function messageBox({
messageBox.element = null; messageBox.element = null;
messageBox.resolve = null; messageBox.resolve = null;
} }
function moveFocus(dir) {
const elements = [...messageBox.element.getElementsByTagName('*')];
const activeIndex = elements.indexOf(document.activeElement);
const num = elements.length;
for (let i = 1; i < num; i++) {
const elementIndex = (activeIndex + i * dir + num) % num;
// we don't use positive tabindex so we stop at any valid value
const el = elements[elementIndex];
if (!el.disabled && el.tabIndex >= 0) {
el.focus();
return;
}
}
}
} }
messageBox.alert = text => messageBox.alert = text =>

View File

@ -117,7 +117,7 @@
<div class="block" id="advanced"> <div class="block" id="advanced">
<div class="collapsible-resizer"> <div class="collapsible-resizer">
<h1 i18n-text="optionsAdvanced" tabindex="0"> <h1 i18n-text="optionsAdvanced">
<svg class="svg-icon is-collapsed" viewBox="0 0 1792 1792"> <svg class="svg-icon is-collapsed" viewBox="0 0 1792 1792">
<path fill-rule="evenodd" d="M1408 704q0 26-19 45l-448 448q-19 19-45 19t-45-19l-448-448q-19-19-19-45t19-45 45-19h896q26 0 45 19t19 45z"/> <path fill-rule="evenodd" d="M1408 704q0 26-19 45l-448 448q-19 19-45 19t-45-19l-448-448q-19-19-19-45t19-45 45-19h896q26 0 45 19t19 45z"/>
</svg> </svg>
@ -158,7 +158,6 @@
</div> </div>
</div> </div>
<script src="vendor/focus/what-input.min.js"></script>
<script src="options/options.js"></script> <script src="options/options.js"></script>
</body> </body>
</html> </html>

View File

@ -13,12 +13,9 @@ if (!FIREFOX && !OPERA) {
} }
}; };
block.classList.add('collapsible', 'collapsed'); block.classList.add('collapsible', 'collapsed');
block.onclick = event => toggleAdvanced(event); block.onclick = toggleAdvanced;
block.onkeydown = event => { block.onkeydown = event => event.which === 13 && toggleAdvanced(event);
if ((event.keyCode || event.which) === 13) { $('h1', block).tabIndex = 0;
toggleAdvanced(event);
}
};
} }
// actions // actions

View File

@ -246,6 +246,5 @@
</symbol> </symbol>
</svg> </svg>
<script src="vendor/focus/what-input.min.js"></script>
</body> </body>
</html> </html>

View File

@ -326,6 +326,7 @@ Object.assign(handleEvent, {
box.dataset.display = true; box.dataset.display = true;
box.style.cssText = ''; box.style.cssText = '';
$('b', box).textContent = (BG.cachedStyles.byId.get(id) || {}).name; $('b', box).textContent = (BG.cachedStyles.byId.get(id) || {}).name;
$('[data-cmd="ok"]', box).focus();
$('[data-cmd="ok"]', box).onclick = () => confirm(true); $('[data-cmd="ok"]', box).onclick = () => confirm(true);
$('[data-cmd="cancel"]', box).onclick = () => confirm(false); $('[data-cmd="cancel"]', box).onclick = () => confirm(false);
window.onkeydown = event => { window.onkeydown = event => {

View File

@ -1,7 +0,0 @@
/**
* what-input - A global utility for tracking the current input method (mouse, keyboard or touch).
* @version v5.0.3
* @link https://github.com/ten1seven/what-input
* @license MIT
*/
!function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t():"function"==typeof define&&define.amd?define("whatInput",[],t):"object"==typeof exports?exports.whatInput=t():e.whatInput=t()}(this,function(){return function(e){function t(o){if(n[o])return n[o].exports;var i=n[o]={exports:{},id:o,loaded:!1};return e[o].call(i.exports,i,i.exports,t),i.loaded=!0,i.exports}var n={};return t.m=e,t.c=n,t.p="",t(0)}([function(e,t){"use strict";e.exports=function(){var e=document.documentElement,t=null,n="initial",o=n,i=null,r=["input","select","textarea"],u=[],d=[16,17,18,91,93],a={keydown:"keyboard",keyup:"keyboard",mousedown:"mouse",mousemove:"mouse",MSPointerDown:"pointer",MSPointerMove:"pointer",pointerdown:"pointer",pointermove:"pointer",touchstart:"touch"},s=!1,c=!1,w={x:null,y:null},p={2:"touch",3:"touch",4:"mouse"},f=!1;try{var l=Object.defineProperty({},"passive",{get:function(){f=!0}});window.addEventListener("test",null,l)}catch(e){}var v=function(){var e=!!f&&{passive:!0};window.PointerEvent?(window.addEventListener("pointerdown",m),window.addEventListener("pointermove",y)):window.MSPointerEvent?(window.addEventListener("MSPointerDown",m),window.addEventListener("MSPointerMove",y)):(window.addEventListener("mousedown",m),window.addEventListener("mousemove",y),"ontouchstart"in window&&(window.addEventListener("touchstart",x,e),window.addEventListener("touchend",m))),window.addEventListener(b(),y,e),window.addEventListener("keydown",x),window.addEventListener("keyup",x),window.addEventListener("focusin",E),window.addEventListener("focusout",L)},m=function(e){if(!s){var t=e.which,i=a[e.type];"pointer"===i&&(i=g(e));var u="keyboard"===i&&t&&-1===d.indexOf(t)||"mouse"===i||"touch"===i;if(n!==i&&u&&(n=i,h("input")),o!==i&&u){var c=document.activeElement;c&&c.nodeName&&-1===r.indexOf(c.nodeName.toLowerCase())&&(o=i,h("intent"))}}},h=function(t){e.setAttribute("data-what"+t,"input"===t?n:o),M(t)},y=function(e){if(O(e),!s&&!c){var t=a[e.type];"pointer"===t&&(t=g(e)),o!==t&&(o=t,h("intent"))}},E=function(n){t=n.target.nodeName.toLowerCase(),e.setAttribute("data-whatelement",t),n.target.classList&&n.target.classList.length&&e.setAttribute("data-whatclasses",n.target.classList.toString().replace(" ",","))},L=function(){t=null,e.removeAttribute("data-whatelement"),e.removeAttribute("data-whatclasses")},x=function(e){m(e),window.clearTimeout(i),s=!0,i=window.setTimeout(function(){s=!1},100)},g=function(e){return"number"==typeof e.pointerType?p[e.pointerType]:"pen"===e.pointerType?"touch":e.pointerType},b=function(){return"onwheel"in document.createElement("div")?"wheel":void 0!==document.onmousewheel?"mousewheel":"DOMMouseScroll"},M=function(e){for(var t=0,i=u.length;t<i;t++)u[t].type===e&&u[t].fn.call(void 0,"input"===e?n:o)},k=function(e){for(var t=0,n=u.length;t<n;t++)if(u[t].fn===e)return t},O=function(e){w.x!==e.screenX||w.y!==e.screenY?(c=!1,w.x=e.screenX,w.y=e.screenY):c=!0};return"addEventListener"in window&&Array.prototype.indexOf&&function(){a[b()]="mouse",v(),h("input"),h("intent")}(),{ask:function(e){return"intent"===e?o:n},element:function(){return t},ignoreKeys:function(e){d=e},registerOnChange:function(e,t){u.push({fn:e,type:t||"input"})},unRegisterOnChange:function(e){var t=k(e);t&&u.splice(t,1)}}}()}])});