Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 26 additions & 9 deletions main/blocklyinit.js
Original file line number Diff line number Diff line change
Expand Up @@ -1196,9 +1196,22 @@ export function initializeWorkspace() {
workspaceSearch.preserveSelected
);
});
// Up/Down step through matches without leaving the search box; the plugin only binds Enter
const wsSearchArrowKeys = (e) => {
if (e.key !== 'ArrowDown' && e.key !== 'ArrowUp') return;
e.preventDefault();
e.stopPropagation();
if (!workspaceSearch.blocks?.length) return;
if (e.key === 'ArrowDown') workspaceSearch.next();
else workspaceSearch.previous();
};

workspaceSearch.inputElement?.addEventListener('keydown', wsSearchArrowKeys);

wsMobileInput.addEventListener('keydown', (e) => {
if (e.key === 'Escape') workspaceSearch.close();
else if (e.key === 'Enter') e.shiftKey ? workspaceSearch.previous() : workspaceSearch.next();
else wsSearchArrowKeys(e);
});
wsMobilePrev.addEventListener('mousedown', (e) => e.preventDefault());
wsMobilePrev.addEventListener('click', () => workspaceSearch.previous());
Expand Down Expand Up @@ -1256,20 +1269,24 @@ export function initializeWorkspace() {
block.getSvgRoot()?.classList.remove('ws-search-fade');
});
};
// The current match is just the selected block, so Blockly renders it correctly for every block shape
workspaceSearch.highlightCurrentSelection = function (block) {
const svg = block.getSvgRoot();
if (svg) {
svg.classList.add('ws-search-current');
let top = block;
while (top.getSurroundParent()) top = top.getSurroundParent();
const topSvg = top.getSvgRoot();
if (topSvg) topSvg.parentNode?.appendChild(topSvg);
}
block.select?.();
};
workspaceSearch.unhighlightCurrentSelection = function (block) {
block.getSvgRoot()?.classList.remove('ws-search-current');
block.unselect?.();
};

// Selecting a matched block makes it the current result, so search and selection stay in step
workspace.addChangeListener((event) => {
if (event.type !== Blockly.Events.SELECTED || !event.newElementId) return;
if (!blocklyDiv?.classList.contains('blockly-search-active')) return;
const index = workspaceSearch.blocks?.findIndex((b) => b.id === event.newElementId) ?? -1;
if (index >= 0 && index !== workspaceSearch.currentBlockIndex) {
workspaceSearch.setCurrentBlock(index);
}
});

// Override the workspace centering for workspace search as it jumps all over the place by default!
const originalCenter = workspace.centerOnBlock.bind(workspace);

Expand Down
21 changes: 5 additions & 16 deletions style/blockly.css
Original file line number Diff line number Diff line change
Expand Up @@ -246,37 +246,26 @@ body[data-theme='low-vision'] {
transition: opacity 0.15s ease;
}

/* Non-current matches get a pale yellow background (desktop only) */
/* Matches get a pale yellow background (desktop only); the current match is the selected block.
.blocklyPathSelected shares the blocklyPath class; filling it makes the selection glow filter flood the block. */
@media (min-width: 769px) {
#blocklyDiv.blockly-search-active .ws-search-match:not(.ws-search-current) > path.blocklyPath {
#blocklyDiv.blockly-search-active .ws-search-match > path.blocklyPath:not(.blocklyPathSelected) {
fill: rgba(255, 242, 0, 0.3) !important;
}
}

/* Low-vision: replace fill with a dashed white stroke for better contrast */
[data-theme='low-vision']
#blocklyDiv.blockly-search-active
.ws-search-match:not(.ws-search-current)
> path.blocklyPath {
.ws-search-match
> path.blocklyPath:not(.blocklyPathSelected) {
fill: revert !important;
stroke: #ffffff !important;
stroke-width: 10px !important;
stroke-dasharray: 8 4;
paint-order: stroke fill;
}

/* Current match gets a yellow outline */
#blocklyDiv.blockly-search-active .ws-search-current > path.blocklyPath {
stroke: var(--block-outline-focus) !important;
stroke-width: 10px !important;
paint-order: stroke fill;
}

/* Suppress the Zelos selection glow path when the search outline is already showing */
#blocklyDiv.blockly-search-active .ws-search-current > path.blocklyPathSelected {
display: none;
}

@media (min-width: 769px) {
.blocklyTreeRow {
flex-direction: row;
Expand Down
Loading