split button for manage::export, popup::manage
This commit is contained in:
parent
b692cf9608
commit
6a07ad0f56
|
@ -392,6 +392,9 @@
|
||||||
"message": "Export",
|
"message": "Export",
|
||||||
"description": "Label for the button to export a style ('edit' page) or all styles ('manage' page)"
|
"description": "Label for the button to export a style ('edit' page) or all styles ('manage' page)"
|
||||||
},
|
},
|
||||||
|
"exportCompatible": {
|
||||||
|
"message": "Export (compatible mode)"
|
||||||
|
},
|
||||||
"exportSavedSuccess": {
|
"exportSavedSuccess": {
|
||||||
"message": "File saved with success"
|
"message": "File saved with success"
|
||||||
},
|
},
|
||||||
|
@ -1269,6 +1272,10 @@
|
||||||
"message": "Click to see available hotkeys",
|
"message": "Click to see available hotkeys",
|
||||||
"description": "Tooltip displayed when hovering the right edge of the extension popup"
|
"description": "Tooltip displayed when hovering the right edge of the extension popup"
|
||||||
},
|
},
|
||||||
|
"popupManageSiteStyles": {
|
||||||
|
"message": "Manage site styles",
|
||||||
|
"description": "Item in the dropdown menu for the 'Manage' button in the popup that opens manager with styles applicable for current site."
|
||||||
|
},
|
||||||
"popupManageTooltip": {
|
"popupManageTooltip": {
|
||||||
"message": "Shift-click or right-click opens manager with styles applicable for current site",
|
"message": "Shift-click or right-click opens manager with styles applicable for current site",
|
||||||
"description": "Tooltip for the 'Manage' button in the popup."
|
"description": "Tooltip for the 'Manage' button in the popup."
|
||||||
|
|
|
@ -315,6 +315,7 @@ body.resizing-v > * {
|
||||||
margin-left: -1px !important;
|
margin-left: -1px !important;
|
||||||
padding-left: .2em !important;
|
padding-left: .2em !important;
|
||||||
padding-right: .2em !important;
|
padding-right: .2em !important;
|
||||||
|
min-width: 0 !important;
|
||||||
}
|
}
|
||||||
.split-btn-pedal::after {
|
.split-btn-pedal::after {
|
||||||
content: '\25BC'; /* down triangle */
|
content: '\25BC'; /* down triangle */
|
||||||
|
@ -384,12 +385,6 @@ body.resizing-v > * {
|
||||||
padding: 4px;
|
padding: 4px;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Firefox cannot handle fractions in font-size */
|
|
||||||
.firefox button:not(.install) {
|
|
||||||
line-height: 13px;
|
|
||||||
padding: 3px 7px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.firefox.moz-appearance-bug button:not(.install) {
|
.firefox.moz-appearance-bug button:not(.install) {
|
||||||
padding: 2px 4px;
|
padding: 2px 4px;
|
||||||
}
|
}
|
||||||
|
|
|
@ -85,20 +85,31 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {PointerEvent} [event] - absent when self-invoked to hide the menu
|
||||||
|
*/
|
||||||
function splitMenu(event) {
|
function splitMenu(event) {
|
||||||
const prevMenu = $(SPLIT_BTN_MENU);
|
const prevMenu = $(SPLIT_BTN_MENU);
|
||||||
const prevPedal = (prevMenu || {}).previousElementSibling;
|
const prevPedal = (prevMenu || {}).previousElementSibling;
|
||||||
const pedal = event.target.closest('.split-btn-pedal');
|
const pedal = event && event.target.closest('.split-btn-pedal');
|
||||||
const entry = prevMenu && event.target.closest(SPLIT_BTN_MENU + '>*');
|
const entry = event && prevMenu && event.target.closest(SPLIT_BTN_MENU + '>*');
|
||||||
if (prevMenu) prevMenu.remove();
|
if (prevMenu) {
|
||||||
if (prevPedal) prevPedal.classList.remove('active');
|
prevMenu.remove();
|
||||||
|
prevPedal.classList.remove('active');
|
||||||
|
window.off('keydown', splitMenuEscape);
|
||||||
|
}
|
||||||
if (pedal && pedal !== prevPedal) {
|
if (pedal && pedal !== prevPedal) {
|
||||||
const menu = $create(SPLIT_BTN_MENU,
|
const menu = $create(SPLIT_BTN_MENU,
|
||||||
Array.from(pedal.attributes, ({name, value}) =>
|
Array.from(pedal.attributes, ({name, value}) =>
|
||||||
name.startsWith('menu-') &&
|
name.startsWith('menu-') &&
|
||||||
$create('a', {tabIndex: 0, __cmd: name.split('-').pop()}, value)
|
$create('a', {tabIndex: 0, __cmd: name.split('-').pop()}, value)
|
||||||
));
|
));
|
||||||
menu.on('focusout', e => e.target === menu && splitMenu(e));
|
window.on('keydown', splitMenuEscape);
|
||||||
|
menu.on('focusout', e => {
|
||||||
|
if (!menu.contains(e.relatedTarget)) {
|
||||||
|
setTimeout(splitMenu);
|
||||||
|
}
|
||||||
|
});
|
||||||
pedal.classList.toggle('active');
|
pedal.classList.toggle('active');
|
||||||
pedal.after(menu);
|
pedal.after(menu);
|
||||||
moveFocus(menu, 0);
|
moveFocus(menu, 0);
|
||||||
|
@ -112,6 +123,13 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function splitMenuEscape(e) {
|
||||||
|
if (getEventKeyName(e) === 'Escape') {
|
||||||
|
e.preventDefault();
|
||||||
|
splitMenu();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function suppressFocusRingOnClick({target}) {
|
function suppressFocusRingOnClick({target}) {
|
||||||
const el = focusAccessibility.closest(target);
|
const el = focusAccessibility.closest(target);
|
||||||
if (el) {
|
if (el) {
|
||||||
|
|
|
@ -328,7 +328,10 @@
|
||||||
</h2>
|
</h2>
|
||||||
</summary>
|
</summary>
|
||||||
<div id="backup-buttons">
|
<div id="backup-buttons">
|
||||||
<button id="file-all-styles" i18n-text="exportLabel"></button>
|
<div class="split-btn">
|
||||||
|
<button id="file-all-styles" i18n-text="exportLabel"></button
|
||||||
|
><button class="split-btn-pedal" i18n-menu-compat="exportCompatible"></button>
|
||||||
|
</div>
|
||||||
<button id="unfile-all-styles" i18n-text="importLabel"></button>
|
<button id="unfile-all-styles" i18n-text="importLabel"></button>
|
||||||
<button id="sync-styles" i18n-text="optionsCustomizeSync"></button>
|
<button id="sync-styles" i18n-text="optionsCustomizeSync"></button>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -14,8 +14,11 @@
|
||||||
*/// dom.js
|
*/// dom.js
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
$('#file-all-styles').onclick = exportToFile;
|
Object.assign($('#file-all-styles'), {
|
||||||
$('#file-all-styles').oncontextmenu = exportToFile;
|
onclick: exportToFile,
|
||||||
|
oncontextmenu: exportToFile,
|
||||||
|
onauxclick: exportToFile,
|
||||||
|
});
|
||||||
$('#unfile-all-styles').onclick = () => importFromFile({fileTypeFilter: '.json'});
|
$('#unfile-all-styles').onclick = () => importFromFile({fileTypeFilter: '.json'});
|
||||||
|
|
||||||
Object.assign(document.body, {
|
Object.assign(document.body, {
|
||||||
|
@ -336,9 +339,12 @@ async function importFromString(jsonString) {
|
||||||
|
|
||||||
/** @param {MouseEvent} e */
|
/** @param {MouseEvent} e */
|
||||||
async function exportToFile(e) {
|
async function exportToFile(e) {
|
||||||
|
if (e.type === 'auxclick' && !e.detail) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
await require(['/js/storage-util']);
|
await require(['/js/storage-util']);
|
||||||
const keepDupSections = e.type === 'contextmenu' || e.shiftKey;
|
const keepDupSections = e.type === 'contextmenu' || e.shiftKey || e.detail === 'compat';
|
||||||
const data = [
|
const data = [
|
||||||
Object.assign({
|
Object.assign({
|
||||||
[prefs.STORAGE_KEY]: prefs.values,
|
[prefs.STORAGE_KEY]: prefs.values,
|
||||||
|
|
|
@ -262,7 +262,7 @@ a:hover {
|
||||||
flex-wrap: wrap;
|
flex-wrap: wrap;
|
||||||
}
|
}
|
||||||
|
|
||||||
#backup-buttons button {
|
#backup-buttons > * {
|
||||||
margin: 0 .2rem .5rem 0;
|
margin: 0 .2rem .5rem 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -219,8 +219,11 @@
|
||||||
|
|
||||||
<!-- Actions -->
|
<!-- Actions -->
|
||||||
<div id="popup-options">
|
<div id="popup-options">
|
||||||
|
<div class="split-btn">
|
||||||
<button id="popup-manage-button" i18n-text="openManage"
|
<button id="popup-manage-button" i18n-text="openManage"
|
||||||
data-href="manage.html" i18n-title="popupManageTooltip"></button>
|
data-href="manage.html" i18n-title="popupManageTooltip"></button
|
||||||
|
><button class="split-btn-pedal" i18n-menu-site="popupManageSiteStyles"></button>
|
||||||
|
</div>
|
||||||
<button id="popup-options-button" i18n-text="openOptions"></button>
|
<button id="popup-options-button" i18n-text="openOptions"></button>
|
||||||
<button id="popup-wiki-button"
|
<button id="popup-wiki-button"
|
||||||
i18n-text="linkStylusWiki"
|
i18n-text="linkStylusWiki"
|
||||||
|
|
|
@ -110,7 +110,7 @@ const Events = {
|
||||||
|
|
||||||
async openManager(event) {
|
async openManager(event) {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
const isSearch = tabURL && (event.shiftKey || event.button === 2);
|
const isSearch = tabURL && (event.shiftKey || event.button === 2 || event.detail === 'site');
|
||||||
await API.openManage(isSearch ? {search: tabURL, searchMode: 'url'} : {});
|
await API.openManage(isSearch ? {search: tabURL, searchMode: 'url'} : {});
|
||||||
window.close();
|
window.close();
|
||||||
},
|
},
|
||||||
|
|
|
@ -668,20 +668,30 @@ body.blocked .actions > .main-controls {
|
||||||
flex-direction: row;
|
flex-direction: row;
|
||||||
padding: var(--outer-padding) 1px;
|
padding: var(--outer-padding) 1px;
|
||||||
}
|
}
|
||||||
|
#popup-options .split-btn {
|
||||||
|
display: flex;
|
||||||
|
}
|
||||||
#popup-options button {
|
#popup-options button {
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
text-overflow: ellipsis;
|
text-overflow: ellipsis;
|
||||||
padding: 2px 4px;
|
padding: 2px 4px;
|
||||||
|
}
|
||||||
|
#popup-options > :nth-last-child(n + 2) {
|
||||||
margin-right: 4px;
|
margin-right: 4px;
|
||||||
|
}
|
||||||
|
#popup-options > *,
|
||||||
|
#popup-manage-button {
|
||||||
/* several languages have labels of wildly different lengths so we try to maintain the proportion */
|
/* several languages have labels of wildly different lengths so we try to maintain the proportion */
|
||||||
flex: 1 1 auto;
|
flex: 1 1 auto;
|
||||||
min-width: 2em;
|
min-width: 2em;
|
||||||
}
|
}
|
||||||
|
#popup-manage-button + .split-btn-pedal::after {
|
||||||
#popup-options button:last-child {
|
content: '\25B2'; /* up triangle */
|
||||||
margin-right: 0;
|
}
|
||||||
|
#popup-manage-button ~ .split-btn-menu {
|
||||||
|
bottom: 0;
|
||||||
|
transform: translateY(-20px); /* global button style: 13(font) * 1.2(line) + 4(pad) + 2(border) */
|
||||||
}
|
}
|
||||||
|
|
||||||
/* confirm */
|
/* confirm */
|
||||||
|
|
|
@ -103,6 +103,7 @@ async function initPopup(frames) {
|
||||||
Object.assign($('#popup-manage-button'), {
|
Object.assign($('#popup-manage-button'), {
|
||||||
onclick: Events.openManager,
|
onclick: Events.openManager,
|
||||||
oncontextmenu: Events.openManager,
|
oncontextmenu: Events.openManager,
|
||||||
|
onauxclick: Events.openManager,
|
||||||
});
|
});
|
||||||
|
|
||||||
$('#popup-options-button').onclick = () => {
|
$('#popup-options-button').onclick = () => {
|
||||||
|
|
Loading…
Reference in New Issue
Block a user