Manage: Disable tabindex in nested buttons
Manage: Fix homepage link alignment
Manage: Make entry actions keyboard navigatable
Manage: Add search help accessibility
Msgbox: Save and restore focus
Manage: Fix delete confirmation cancel
Manage: Make history button accessible
Manage: Make favicons dropdown accessible
Manage: Prevent focus on hidden textarea
Msgbox: Stop tabbing outside of msgbox
Usercss: Make nondefault reset accessible
Usercss: Make colorpicker accessible
Edit: Disable tabindex in nested buttons
Edit: Make info and config icons accessible
Options: Cleanup HTML
Options: Make advanced toggle accessible
Edit: Fix issues popup
Edit: Remove link underlines from icons
This commit is contained in:
Rob Garrison 2017-12-09 18:25:44 +03:00 committed by tophf
parent e2842f69c3
commit 2cdd264780
14 changed files with 200 additions and 85 deletions

View File

@ -191,17 +191,19 @@
<label id="enabled-label" i18n-text="styleEnabledLabel"> <label id="enabled-label" i18n-text="styleEnabledLabel">
<input type="checkbox" id="enabled" class="style-contributor"> <input type="checkbox" id="enabled" class="style-contributor">
<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>
--><svg id="toggle-style-help" class="svg-icon info"> <a href="#" id="toggle-style-help" class="svg-inline-wrapper">
<use xlink:href="#svg-icon-help"/> <svg class="svg-icon info">
</svg> <use xlink:href="#svg-icon-help"/>
</svg>
</a>
</div> </div>
</section> </section>
<section id="actions"> <section id="actions">
<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"></button></a> <a href="manage.html"><button id="cancel-button" i18n-text="styleCancelEditLabel" tabindex="-1"></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"><svg id="to-mozilla-help" class="svg-icon info"><use xlink:href="#svg-icon-help"/></svg></h2>
@ -246,11 +248,11 @@
<input id="editor.colorpicker" type="checkbox"> <input id="editor.colorpicker" type="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>
</label> </label>
<span class="svg-inline-wrapper" i18n-title="shortcutsNote"> <a id="colorpicker-settings" href="#" class="svg-inline-wrapper" i18n-title="shortcutsNote">
<svg id="colorpicker-settings" class="svg-icon settings"> <svg class="svg-icon settings">
<use xlink:href="#svg-icon-settings"/> <use xlink:href="#svg-icon-settings"/>
</svg> </svg>
</span> </a>
</div> </div>
<div class="option usercss-only"> <div class="option usercss-only">
<label i18n-text="appliesLineWidgetLabel" i18n-title="appliesLineWidgetWarning"> <label i18n-text="appliesLineWidgetLabel" i18n-title="appliesLineWidgetWarning">
@ -268,9 +270,9 @@
<select id="editor.keyMap"></select> <select id="editor.keyMap"></select>
<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>
<span class="svg-inline-wrapper"> <a id="keyMap-help" href="#" class="svg-inline-wrapper">
<svg id="keyMap-help" class="svg-icon info"><use xlink:href="#svg-icon-help"/></svg> <svg class="svg-icon info"><use xlink:href="#svg-icon-help"/></svg>
</span> </a>
</div> </div>
<div class="option aligned"> <div class="option aligned">
<label id="theme-label" for="editor.theme" i18n-text="cm_theme"></label> <label id="theme-label" for="editor.theme" i18n-text="cm_theme"></label>
@ -300,20 +302,21 @@
</select> </select>
<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>
<span class="svg-inline-wrapper" i18n-title="linterConfigTooltip"> <a id="linter-settings" href="#" class="svg-inline-wrapper" i18n-title="linterConfigTooltip">
<svg id="linter-settings" class="svg-icon settings"> <svg class="svg-icon settings">
<use xlink:href="#svg-icon-settings"/> <use xlink:href="#svg-icon-settings"/>
</svg> </svg>
</span> </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><!-- EAT SPACE <h2 i18n-text="linterIssues">: <span id="issue-count"></span></h2>
--><svg id="lint-help" class="svg-icon info intercepts-click"> <a id="lint-help" href="#" class="svg-inline-wrapper">
<svg class="svg-icon info intercepts-click">
<use xlink:href="#svg-icon-help"/> <use xlink:href="#svg-icon-help"/>
</svg> </svg>
</h2> </a>
</summary> </summary>
<div></div> <div></div>
</details> </details>

View File

@ -76,6 +76,19 @@ 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;

View File

@ -512,7 +512,8 @@ function showToMozillaHelp() {
showHelp(t('styleMozillaFormatHeading'), t('styleToMozillaFormatHelp')); showHelp(t('styleMozillaFormatHeading'), t('styleToMozillaFormatHelp'));
} }
function showToggleStyleHelp() { function showToggleStyleHelp(event) {
event.preventDefault();
showHelp(t('helpAlt'), t('styleEnabledToggleHint')); showHelp(t('helpAlt'), t('styleEnabledToggleHint'));
} }

View File

@ -41,7 +41,7 @@
</p> </p>
<p class="actions"> <p class="actions">
<a class="style-edit-link"> <a class="style-edit-link">
<button i18n-text="editStyleLabel"></button> <button i18n-text="editStyleLabel" tabindex="-1"></button>
</a> </a>
<button class="enable" i18n-text="enableStyleLabel"></button> <button class="enable" i18n-text="enableStyleLabel"></button>
<button class="disable" i18n-text="disableStyleLabel"></button> <button class="disable" i18n-text="disableStyleLabel"></button>
@ -64,16 +64,16 @@
</h2> </h2>
<p class="actions"> <p class="actions">
<a target="_blank" class="homepage"></a> <a target="_blank" class="homepage"></a>
<span i18n-title="deleteStyleLabel"> <a href="#" class="delete" i18n-title="deleteStyleLabel">
<svg class="svg-icon delete" viewBox="0 0 20 20"> <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 <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
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 "/>
</svg> </svg>
</span> </a>
</p> </p>
<div class="applies-to"> <div class="applies-to">
<div class="targets"></div> <div class="targets"></div>
<span class="expander">...</span> <a href="#" class="expander">...</a>
</div> </div>
</div> </div>
</template> </template>
@ -92,27 +92,27 @@
</template> </template>
<template data-id="configureIcon"> <template data-id="configureIcon">
<span class="configure-usercss" i18n-title="configureStyle"> <a href="#" class="configure-usercss" i18n-title="configureStyle">
<svg class="svg-icon config"><use xlink:href="#svg-icon-config"></use></svg> <svg class="svg-icon config"><use xlink:href="#svg-icon-config"></use></svg>
</span> </a>
</template> </template>
<template data-id="updaterIcons"> <template data-id="updaterIcons">
<span class="updater-icons"> <span class="updater-icons">
<span class="check-update" i18n-title="checkForUpdate"> <a href="#" class="check-update" i18n-title="checkForUpdate">
<svg class="svg-icon" viewBox="0 0 20 20"> <svg class="svg-icon" viewBox="0 0 20 20">
<path d="M18,16.6l-3.1-3.1c0.5-0.7,0.9-1.5,1-2.5h-2.1c-0.4,1.7-2,3-3.9,3c-0.8,0-1.6-0.3-2.3-0.7 <path d="M18,16.6l-3.1-3.1c0.5-0.7,0.9-1.5,1-2.5h-2.1c-0.4,1.7-2,3-3.9,3c-0.8,0-1.6-0.3-2.3-0.7
L10,11H6.1H4.1H4v6l2.3-2.3c1,0.8,2.3,1.3,3.7,1.3c1.3,0,2.5-0.4,3.5-1.1l3.1,3.1L18,16.6z"/> L10,11H6.1H4.1H4v6l2.3-2.3c1,0.8,2.3,1.3,3.7,1.3c1.3,0,2.5-0.4,3.5-1.1l3.1,3.1L18,16.6z"/>
<path d="M10,6c0.8,0,1.6,0.3,2.3,0.7L10,9h3.9h2.1H16V3l-2.3,2.3C12.7,4.5,11.4,4,10,4 <path d="M10,6c0.8,0,1.6,0.3,2.3,0.7L10,9h3.9h2.1H16V3l-2.3,2.3C12.7,4.5,11.4,4,10,4
C7,4,4.6,6.2,4.1,9h2.1C6.6,7.3,8.1,6,10,6z"/> C7,4,4.6,6.2,4.1,9h2.1C6.6,7.3,8.1,6,10,6z"/>
</svg> </svg>
</span> </a>
<span class="update" i18n-title="installUpdate"> <a href="#" class="update" i18n-title="installUpdate">
<svg class="svg-icon" viewBox="0 0 20 20"> <svg class="svg-icon" viewBox="0 0 20 20">
<polygon points="16,8 12,8 12,3 8,3 8,8 4,8 10,14 "/> <polygon points="16,8 12,8 12,3 8,3 8,8 4,8 10,14 "/>
<rect shape-rendering="crispEdges" x="4" y="15" width="12" height="2"/> <rect shape-rendering="crispEdges" x="4" y="15" width="12" height="2"/>
</svg> </svg>
</span> </a>
<span class="up-to-date" i18n-title="updateCheckSucceededNoUpdate"> <span class="up-to-date" i18n-title="updateCheckSucceededNoUpdate">
<svg class="svg-icon" viewBox="0 0 20 20"> <svg class="svg-icon" viewBox="0 0 20 20">
<polygon points="15.83 4.75 8.76 11.82 5.2 8.26 3.51 9.95 8.76 15.19 17.52 6.43 15.83 4.75"/> <polygon points="15.83 4.75 8.76 11.82 5.2 8.26 3.51 9.95 8.76 15.19 17.52 6.43 15.83 4.75"/>
@ -239,18 +239,20 @@
<input id="search" type="search" i18n-placeholder="searchStyles" spellcheck="false" <input id="search" type="search" i18n-placeholder="searchStyles" spellcheck="false"
data-filter=":not(.not-matching)" data-filter=":not(.not-matching)"
data-filter-hide=".not-matching"> data-filter-hide=".not-matching">
<svg id="search-help" class="svg-icon info"><use xlink:href="#svg-icon-help"/></svg> <a href="#" id="search-help">
<svg class="svg-icon info"><use xlink:href="#svg-icon-help"/></svg>
</a>
</div> </div>
</details> </details>
<p class="nowrap"> <p class="nowrap">
<button id="check-all-updates" i18n-text="checkAllUpdates"><span id="update-progress"></span></button> <button id="check-all-updates" i18n-text="checkAllUpdates"><span id="update-progress"></span></button>
<span id="update-history" i18n-title="genericHistoryLabel"> <a href="#" id="update-history" i18n-title="genericHistoryLabel">
<svg class="svg-icon" viewBox="0 0 20 20" i18n-alt="helpAlt"> <svg class="svg-icon" viewBox="0 0 20 20" i18n-alt="helpAlt">
<path d="M13,7H7V6h6Zm6,6.5A5.5,5.5,0,0,1,8.61,16H4V3H16V8.61A5.5,5.5,0,0,1,19,13.5ZM8,14c0-.16,0-.84,0-1H7V12H8.21a5.46,5.46,0,0,1,.39-1H7V10H9.26a5.55,5.55,0,0,1,1.09-1H7V8h7V5H6v9Zm10-.5A4.5,4.5,0,1,0,13.5,18,4.5,4.5,0,0,0,18,13.5ZM14,13V10H13v4h4V13Z"/> <path d="M13,7H7V6h6Zm6,6.5A5.5,5.5,0,0,1,8.61,16H4V3H16V8.61A5.5,5.5,0,0,1,19,13.5ZM8,14c0-.16,0-.84,0-1H7V12H8.21a5.46,5.46,0,0,1,.39-1H7V10H9.26a5.55,5.55,0,0,1,1.09-1H7V8h7V5H6v9Zm10-.5A4.5,4.5,0,1,0,13.5,18,4.5,4.5,0,0,0,18,13.5ZM14,13V10H13v4h4V13Z"/>
</svg> </svg>
</span> </a>
</p> </p>
<p> <p>
@ -261,7 +263,7 @@
<div id="add-style-wrapper"> <div id="add-style-wrapper">
<a href="edit.html"> <a href="edit.html">
<button id="add-style-label" i18n-text="addStyleLabel"></button> <button id="add-style-label" i18n-text="addStyleLabel" tabindex="-1"></button>
</a> </a>
<label id="add-style-as-usercss-wrapper"> <label id="add-style-as-usercss-wrapper">
<input type="checkbox" id="newStyleAsUsercss"> <input type="checkbox" id="newStyleAsUsercss">
@ -292,10 +294,12 @@
<label for="manage.newUI.favicons" i18n-text="manageFavicons"> <label for="manage.newUI.favicons" i18n-text="manageFavicons">
<input id="manage.newUI.favicons" type="checkbox"> <input id="manage.newUI.favicons" type="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>
<svg class="svg-icon select-arrow" data-toggle-on-click="#faviconsHelp"> <a href="#" data-toggle-on-click="#faviconsHelp">
<title i18n-text="optionsSubheading"></title> <svg class="svg-icon select-arrow">
<use xlink:href="#svg-icon-select-arrow"/> <title i18n-text="optionsSubheading"></title>
</svg> <use xlink:href="#svg-icon-select-arrow"/>
</svg>
</a>
</label> </label>
<div id="faviconsHelp" class="hidden" i18n-text="manageFaviconsHelp"> <div id="faviconsHelp" class="hidden" i18n-text="manageFaviconsHelp">
<div> <div>
@ -317,7 +321,7 @@
<a id="find-editor-styles" <a id="find-editor-styles"
href="https://userstyles.org/styles/browse/chrome-extension" href="https://userstyles.org/styles/browse/chrome-extension"
i18n-title="editorStylesButton" i18n-title="editorStylesButton"
target="_blank"><button i18n-text="cm_theme"></button></a> target="_blank"><button i18n-text="cm_theme" tabindex="-1"></button></a>
</p> </p>
</details> </details>

View File

@ -93,13 +93,18 @@
margin-right: 4px; margin-right: 4px;
} }
.config-body label:not(.nondefault) .config-reset-icon { .config-reset-icon {
visibility: hidden; width: 16px;
display: inline-block;
} }
.svg-icon.config-reset-icon { .config-body label:not(.nondefault) .config-reset-icon a {
display: none;
}
.config-reset-icon .svg-icon {
/*position: absolute;*/ /*position: absolute;*/
pointer-events: all !important; pointer-events: none;
cursor: pointer; cursor: pointer;
/*right: -7px;*/ /*right: -7px;*/
fill: #aaa; fill: #aaa;
@ -110,7 +115,7 @@
flex-shrink: 0; flex-shrink: 0;
} }
.svg-icon.config-reset-icon:hover { .config-reset-icon:hover .svg-icon {
fill: #666; fill: #666;
} }
@ -155,9 +160,11 @@
.color-swatch { .color-swatch {
position: absolute; position: absolute;
top: 0;
left: 0;
border: 1px solid gray; border: 1px solid gray;
margin-top: -22px;
cursor: pointer; cursor: pointer;
opacity: 1;
} }
.colorpicker-popup { .colorpicker-popup {

View File

@ -30,13 +30,13 @@ function configDialog(style) {
], ],
buttons: [{ buttons: [{
textContent: t('confirmSave'), textContent: t('confirmSave'),
dataset: {cmd: 'save'}, dataset: {cmd: 'save', allowEnter: true},
disabled: true, disabled: true,
onclick: save, onclick: save,
}, { }, {
textContent: t('genericResetLabel'), textContent: t('genericResetLabel'),
title: t('optionsReset'), title: t('optionsReset'),
dataset: {cmd: 'default'}, dataset: {cmd: 'default', allowEnter: true},
onclick: useDefault, onclick: useDefault,
}, { }, {
textContent: t('confirmClose'), textContent: t('confirmClose'),
@ -78,7 +78,13 @@ function configDialog(style) {
updateButtons(); updateButtons();
} }
function onhide() { function onhide({button, enter}) {
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();
@ -195,12 +201,16 @@ function configDialog(style) {
} }
function buildConfigForm() { function buildConfigForm() {
let resetter = $create('SVG:svg.svg-icon.config-reset-icon', {viewBox: '0 0 20 20'}, [ let resetter = $create('span.config-reset-icon', [
$create('SVG:title', t('genericResetLabel')), $create('a', {href:'#', dataset: {allowEnter: true}}, [
$create('SVG:polygon', { $create('SVG:svg.svg-icon', {viewBox: '0 0 20 20'}, [
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 ' + $create('SVG:title', t('genericResetLabel')),
'5.5,16.2 10,11.7 14.5,16.2 16.2,14.5 11.7,10', $create('SVG: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 ' +
'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;
@ -208,8 +218,10 @@ function configDialog(style) {
case 'color': case 'color':
children = [ children = [
$create('.cm-colorview.config-value', [ $create('.cm-colorview.config-value', [
va.input = $create('.color-swatch', { va.input = $create('a.color-swatch', {
va, va,
href: '#',
dataset: {allowEnter: true},
onclick: showColorpicker onclick: showColorpicker
}), }),
]), ]),
@ -260,8 +272,8 @@ function configDialog(style) {
} }
resetter = resetter.cloneNode(true); resetter = resetter.cloneNode(true);
resetter.va = va; $('a', resetter).va = va;
resetter.onclick = resetOnClick; $('a', resetter).onclick = resetOnClick;
elements.push( elements.push(
$create(`label.config-${va.type}`, [ $create(`label.config-${va.type}`, [
@ -310,10 +322,16 @@ function configDialog(style) {
} }
function resetOnClick(event) { function resetOnClick(event) {
event.preventDefault(); if (
this.va.value = null; event.type === 'click' ||
renderValues([this.va]); (event.keyCode || event.which) === 13
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() {

View File

@ -31,7 +31,8 @@ onDOMready().then(onBackgroundReady).then(() => {
if (urlFilterParam) { if (urlFilterParam) {
$('#search').value = 'url:' + urlFilterParam; $('#search').value = 'url:' + urlFilterParam;
} }
$('#search-help').onclick = () => { $('#search-help').onclick = event => {
event.preventDefault();
messageBox({ messageBox({
className: 'help-text', className: 'help-text',
title: t('searchStyles'), title: t('searchStyles'),

View File

@ -7,6 +7,7 @@ onDOMready().then(() => {
let focusedName = ''; let focusedName = '';
const input = $create('textarea', { const input = $create('textarea', {
spellcheck: false, spellcheck: false,
attributes: {tabindex: -1},
oninput: incrementalSearch, oninput: incrementalSearch,
}); });
replaceInlineStyle({ replaceInlineStyle({

View File

@ -159,7 +159,7 @@ select {
} }
.homepage .svg-icon { .homepage .svg-icon {
margin-top: -4px; margin-top: 0;
margin-left: .5ex; margin-left: .5ex;
} }
@ -374,6 +374,10 @@ select {
right: 0; right: 0;
} }
#newUIoptions a > .svg-icon.select-arrow {
position: static;
}
.select-resizer { .select-resizer {
cursor: default; cursor: default;
border: none; border: none;
@ -446,10 +450,11 @@ select {
color: hsla(180, 100%, 15%, 1); color: hsla(180, 100%, 15%, 1);
} }
.newUI .homepage .svg-icon { /* align delete button if no homepage link */
position: absolute; .newUI a.homepage.disabled {
margin-top: 0; /* 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 {
@ -466,6 +471,25 @@ select {
margin-right: 8px; 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 > * {
transition: opacity 1s; transition: opacity 1s;
display: none; display: none;
@ -658,7 +682,8 @@ select {
margin-right: .5em; margin-right: .5em;
} }
#newUIoptions [data-toggle-on-click] { #newUIoptions [data-toggle-on-click],
#newUIoptions a[data-toggle-on-click] svg {
transform: rotate(-90deg); transform: rotate(-90deg);
cursor: pointer; cursor: pointer;
right: -16px; right: -16px;
@ -666,7 +691,8 @@ select {
pointer-events: auto; pointer-events: auto;
} }
#newUIoptions [data-toggle-on-click][open] { #newUIoptions [data-toggle-on-click][open],
#newUIoptions a[data-toggle-on-click][open] svg {
transform: none; transform: none;
} }
@ -687,12 +713,12 @@ input[id^="manage.newUI"] {
} }
/* Default, no update buttons */ /* Default, no update buttons */
.update, .updater-icons .update,
.check-update { .updater-icons .check-update {
display: none; display: none;
} }
/* Check update button for things that can*/ /* Check update button for things that can */
.updatable .check-update { .updatable .check-update {
display: inline; display: inline;
} }
@ -836,8 +862,8 @@ input[id^="manage.newUI"] {
border-radius: 0.25rem; border-radius: 0.25rem;
} }
#search-wrapper .info { #search-wrapper #search-help {
margin: 4px -5px 0 8px; margin: 4px 0 0 8px;
} }
#message-box.help-text > div { #message-box.help-text > div {

View File

@ -191,6 +191,9 @@ 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));
@ -334,10 +337,12 @@ Object.assign(handleEvent, {
}, },
check(event, entry) { check(event, entry) {
event.preventDefault();
checkUpdate(entry); checkUpdate(entry);
}, },
update(event, entry) { update(event, entry) {
event.preventDefault();
const request = Object.assign(entry.updatedCode, { const request = Object.assign(entry.updatedCode, {
id: entry.styleId, id: entry.styleId,
reason: 'update', reason: 'update',
@ -353,6 +358,7 @@ Object.assign(handleEvent, {
}, },
delete(event, entry) { delete(event, entry) {
event.preventDefault();
const id = entry.styleId; const id = entry.styleId;
const {name} = BG.cachedStyles.byId.get(id) || {}; const {name} = BG.cachedStyles.byId.get(id) || {};
animateElement(entry); animateElement(entry);
@ -362,8 +368,8 @@ Object.assign(handleEvent, {
className: 'danger center', className: 'danger center',
buttons: [t('confirmDelete'), t('confirmCancel')], buttons: [t('confirmDelete'), t('confirmCancel')],
}) })
.then(({button, enter}) => { .then(({button}) => {
if (button === 0 || enter) { if (button === 0) {
deleteStyleSafe({id}); deleteStyleSafe({id});
} }
}); });
@ -374,7 +380,8 @@ Object.assign(handleEvent, {
event.preventDefault(); event.preventDefault();
}, },
expandTargets() { expandTargets(event) {
event.preventDefault();
this.closest('.applies-to').classList.toggle('expanded'); this.closest('.applies-to').classList.toggle('expanded');
}, },

View File

@ -170,7 +170,8 @@ function renderUpdatesOnlyFilter({show, check} = {}) {
} }
function showUpdateHistory() { function showUpdateHistory(event) {
event.preventDefault();
const log = $create('.update-history-log'); const log = $create('.update-history-log');
let logText, scroller, toggler; let logText, scroller, toggler;
let deleted = false; let deleted = false;
@ -185,6 +186,8 @@ function showUpdateHistory() {
], ],
onshow: logText && (() => { onshow: logText && (() => {
scroller = $('#message-box-contents'); scroller = $('#message-box-contents');
scroller.setAttribute('tabindex', 0);
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
@ -198,6 +201,7 @@ function showUpdateHistory() {
])); ]));
toggler.onchange(); toggler.onchange();
}), }),
blockScroll: true
}); });
}); });
function scrollToBottom() { function scrollToBottom() {

View File

@ -8,6 +8,7 @@ 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();
@ -16,6 +17,11 @@ function messageBox({
onshow(messageBox.element); onshow(messageBox.element);
} }
messageBox.element.focus(); 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;
}); });
@ -30,11 +36,26 @@ function messageBox({
}, },
key(event) { key(event) {
const keyCode = event.keyCode || event.which; const keyCode = event.keyCode || event.which;
if (event.target.closest('#message-box, .colorpicker-popup')) {
messageBox.lastEl = event.target;
}
if (keyCode === 13 && event.target.dataset.allowEnter) {
// usercss item resets needs to activate
return;
}
if (!event.shiftKey && !event.ctrlKey && !event.altKey && !event.metaKey if (!event.shiftKey && !event.ctrlKey && !event.altKey && !event.metaKey
&& (keyCode === 13 || keyCode === 27)) { && (keyCode === 13 || keyCode === 27)) {
event.preventDefault(); event.preventDefault();
event.stopPropagation(); event.stopPropagation();
resolveWith(keyCode === 13 ? {enter: true} : {esc: true}); resolveWith(keyCode === 13 ? {enter: true, button: event.target.buttonIndex} : {esc: true});
}
},
keyup(event) {
const keyCode = event.keyCode || event.which;
if (keyCode === 9 && !event.target.closest('#message-box, .colorpicker-popup')) {
event.preventDefault();
event.stopPropagation();
messageBox.lastEl.focus();
} }
}, },
scroll() { scroll() {
@ -50,6 +71,7 @@ function messageBox({
className: 'fadeout', className: 'fadeout',
onComplete: removeSelf, onComplete: removeSelf,
}); });
messageBox.originalFocus.focus();
} }
function createElement() { function createElement() {
@ -85,10 +107,12 @@ 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);
} }

View File

@ -116,12 +116,12 @@
</div> </div>
<div class="block" id="advanced"> <div class="block" id="advanced">
<div class="collapsible-resizer"> <div class="collapsible-resizer">
<h1 i18n-text="optionsAdvanced"> <h1 i18n-text="optionsAdvanced" tabindex="0">
<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>
<svg class="svg-icon is-expanded" viewBox="0 0 1792 1792"> <svg class="svg-icon is-expanded" viewBox="0 0 1792 1792">
<path fill-rule="evenodd" d="M1408 1216q0 26-19 45t-45 19h-896q-26 0-45-19t-19-45 19-45l448-448q19-19 45-19t45 19l448 448q19 19 19 45z"/> <path fill-rule="evenodd" d="M1408 1216q0 26-19 45t-45 19h-896q-26 0-45-19t-19-45 19-45l448-448q19-19 45-19t45 19l448 448q19 19 19 45z"/>
</svg> </svg>
</h1> </h1>

View File

@ -7,12 +7,18 @@ setTimeout(splitLongTooltips);
if (!FIREFOX && !OPERA) { if (!FIREFOX && !OPERA) {
const block = $('#advanced'); const block = $('#advanced');
block.classList.add('collapsible', 'collapsed'); const toggleAdvanced = event => {
block.onclick = event => {
if (block.classList.contains('collapsed') || event.target.closest('h1')) { if (block.classList.contains('collapsed') || event.target.closest('h1')) {
block.classList.toggle('collapsed'); block.classList.toggle('collapsed');
} }
}; };
block.classList.add('collapsible', 'collapsed');
block.onclick = event => toggleAdvanced(event);
block.onkeydown = event => {
if ((event.keyCode || event.which) === 13) {
toggleAdvanced(event);
}
};
} }
// actions // actions