add incremental search
* support modals in scrollElementIntoView and incremental search
This commit is contained in:
parent
79fcb5705a
commit
30eb6ed4f1
|
@ -2,6 +2,10 @@
|
|||
height: 100%;
|
||||
max-width: 80vw;
|
||||
}
|
||||
.injection-order #incremental-search {
|
||||
transform: scaleY(.55);
|
||||
transform-origin: top;
|
||||
}
|
||||
.injection-order #message-box-contents,
|
||||
.injection-order section {
|
||||
padding: 0;
|
||||
|
@ -19,7 +23,7 @@
|
|||
box-sizing: border-box;
|
||||
}
|
||||
.injection-order ol {
|
||||
padding: 1px 0; /* 1px for keyboard-focused element's outline */
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
font-size: 14px;
|
||||
overflow-y: auto;
|
||||
|
@ -38,6 +42,8 @@
|
|||
.injection-order-entry {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
position: relative; /* for incremental-search */
|
||||
padding: 1px 1px 1px 1rem; /* keyboard focus outline */
|
||||
color: #000;
|
||||
transition: transform .25s ease-in-out;
|
||||
z-index: 1;
|
||||
|
@ -48,7 +54,7 @@
|
|||
cursor: move;
|
||||
}
|
||||
.injection-order-entry a[href] {
|
||||
padding: .4em 0 .4em 1rem;
|
||||
padding: .4em 0;
|
||||
cursor: inherit;
|
||||
}
|
||||
.injection-order-entry.enabled a[href] {
|
||||
|
|
|
@ -36,7 +36,9 @@ async function InjectionOrder(show = true) {
|
|||
entry.classList.toggle('enabled', style.enabled);
|
||||
parts.name.href = '/edit.html?id=' + style.id;
|
||||
parts.name.textContent = style.name;
|
||||
return entry.cloneNode(true);
|
||||
return Object.assign(entry.cloneNode(true), {
|
||||
styleNameLowerCase: style.name.toLocaleLowerCase(),
|
||||
});
|
||||
}
|
||||
|
||||
function makeList([type, styles]) {
|
||||
|
|
|
@ -280,13 +280,14 @@ function onDOMready() {
|
|||
|
||||
function scrollElementIntoView(element, {invalidMarginRatio = 0} = {}) {
|
||||
// align to the top/bottom of the visible area if wasn't visible
|
||||
if (!element.parentNode) return;
|
||||
const parent = element.parentNode;
|
||||
if (!parent) return;
|
||||
const {top, height} = element.getBoundingClientRect();
|
||||
const {top: parentTop, bottom: parentBottom} = element.parentNode.getBoundingClientRect();
|
||||
const {top: parentTop, bottom: parentBottom} = parent.getBoundingClientRect();
|
||||
const windowHeight = window.innerHeight;
|
||||
if (top < Math.max(parentTop, windowHeight * invalidMarginRatio) ||
|
||||
top > Math.min(parentBottom, windowHeight) - height - windowHeight * invalidMarginRatio) {
|
||||
window.scrollBy(0, top - windowHeight / 2 + height);
|
||||
parent.scrollBy(0, top - windowHeight / 2 + height);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
12
manage/incremental-search.css
Normal file
12
manage/incremental-search.css
Normal file
|
@ -0,0 +1,12 @@
|
|||
#incremental-search {
|
||||
position: absolute;
|
||||
color: transparent;
|
||||
border: 1px solid hsla(180, 100%, 50%, .25);
|
||||
margin: -1px -2px;
|
||||
overflow: hidden;
|
||||
resize: none;
|
||||
background-color: hsla(180, 100%, 50%, .1);
|
||||
box-sizing: content-box;
|
||||
pointer-events: none;
|
||||
z-index: 2147483647,
|
||||
}
|
|
@ -1,6 +1,7 @@
|
|||
/* global debounce */// toolbox.js
|
||||
/* global installed */// manage.js
|
||||
/* global
|
||||
$$
|
||||
$
|
||||
$create
|
||||
$isTextInput
|
||||
|
@ -14,39 +15,35 @@
|
|||
let prevTime = performance.now();
|
||||
let focusedName = '';
|
||||
const input = $create('textarea', {
|
||||
id: 'incremental-search',
|
||||
spellcheck: false,
|
||||
attributes: {tabindex: -1},
|
||||
oninput: incrementalSearch,
|
||||
});
|
||||
replaceInlineStyle({
|
||||
opacity: '0',
|
||||
position: 'absolute',
|
||||
color: 'transparent',
|
||||
border: '1px solid hsla(180, 100%, 100%, .5)',
|
||||
margin: '-1px -2px',
|
||||
overflow: 'hidden',
|
||||
resize: 'none',
|
||||
'background-color': 'hsla(180, 100%, 100%, .2)',
|
||||
'box-sizing': 'content-box',
|
||||
'pointer-events': 'none',
|
||||
});
|
||||
document.body.appendChild(input);
|
||||
window.on('keydown', maybeRefocus, true);
|
||||
|
||||
function incrementalSearch({key}, immediately) {
|
||||
function incrementalSearch(event, immediately) {
|
||||
const {key} = event;
|
||||
if (!immediately) {
|
||||
debounce(incrementalSearch, 100, {}, true);
|
||||
return;
|
||||
}
|
||||
const direction = key === 'ArrowUp' ? -1 : key === 'ArrowDown' ? 1 : 0;
|
||||
const text = input.value.toLocaleLowerCase();
|
||||
if (direction) {
|
||||
event.preventDefault();
|
||||
}
|
||||
if (!text.trim() || !direction && (text === prevText || focusedName.startsWith(text))) {
|
||||
prevText = text;
|
||||
return;
|
||||
}
|
||||
let textAtPos = 1e6;
|
||||
let rotated;
|
||||
const entries = [...installed.children];
|
||||
const entries = $('#message-box') ? $$('.injection-order-entry') : [...installed.children];
|
||||
const focusedIndex = entries.indexOf(focusedEntry);
|
||||
if (focusedIndex > 0) {
|
||||
if (direction > 0) {
|
||||
|
@ -74,7 +71,7 @@
|
|||
}
|
||||
if (found && found !== focusedEntry) {
|
||||
focusedEntry = found;
|
||||
focusedLink = $('.style-name-link', found);
|
||||
focusedLink = $('a', found);
|
||||
focusedName = found.styleNameLowerCase;
|
||||
scrollElementIntoView(found, {invalidMarginRatio: .25});
|
||||
animateElement(found, 'highlight-quick');
|
||||
|
@ -84,12 +81,17 @@
|
|||
opacity: '1',
|
||||
});
|
||||
focusedLink.prepend(input);
|
||||
input.focus();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
function maybeRefocus(event) {
|
||||
if (event.altKey || event.metaKey || $('#message-box')) {
|
||||
if (event.altKey || event.metaKey) {
|
||||
return;
|
||||
}
|
||||
const modal = $('#message-box');
|
||||
if (modal && !modal.classList.contains('injection-order')) {
|
||||
return;
|
||||
}
|
||||
const inTextInput = $isTextInput(event.target);
|
||||
|
@ -99,7 +101,7 @@
|
|||
(code === 'Slash' || key === '/') && !ctrl && !inTextInput) {
|
||||
// focus search field on "/" or Ctrl-F key
|
||||
event.preventDefault();
|
||||
$('#search').focus();
|
||||
if (!modal) $('#search').focus();
|
||||
return;
|
||||
}
|
||||
if (ctrl || inTextInput && event.target !== input) {
|
||||
|
|
|
@ -92,11 +92,12 @@ newUI.renderClass();
|
|||
|
||||
showStyles(styles, ids);
|
||||
|
||||
require([
|
||||
window.on('load', () => require([
|
||||
'/manage/import-export',
|
||||
'/manage/incremental-search.css',
|
||||
'/manage/incremental-search',
|
||||
'/manage/updater-ui',
|
||||
]);
|
||||
]), {once: true});
|
||||
})();
|
||||
|
||||
msg.onExtension(onRuntimeMessage);
|
||||
|
|
Loading…
Reference in New Issue
Block a user