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
2 changes: 1 addition & 1 deletion main/blockhandling.js
Original file line number Diff line number Diff line change
Expand Up @@ -591,7 +591,7 @@ function observeBlocklyInputs() {

// Observe only the Blockly container to avoid scanning the entire document
const blocklyContainer =
workspace.getParentSvg()?.closest("#blocklyDiv") ??
workspace?.getParentSvg()?.closest("#blocklyDiv") ??
document.getElementById("blocklyDiv") ??
document.body;
observer.observe(blocklyContainer, { childList: true, subtree: true });
Expand Down
49 changes: 49 additions & 0 deletions main/blocklyinit.js
Original file line number Diff line number Diff line change
Expand Up @@ -647,6 +647,55 @@ export function initializeWorkspace() {
}
workspaceSearch.init();

// Fade non-matching blocks during search
const blocklyDiv = document.getElementById("blocklyDiv");
const originalOpen = workspaceSearch.open.bind(workspaceSearch);
const originalClose = workspaceSearch.close.bind(workspaceSearch);
workspaceSearch.open = function () {
originalOpen();
blocklyDiv?.classList.add("blockly-search-active");
};
workspaceSearch.close = function () {
originalClose();
blocklyDiv?.classList.remove("blockly-search-active");
};

// Override highlight methods to work at block-group level so the plugin's
// injected fill: #000 rule never applies to matched block paths.
workspaceSearch.highlightSearchGroup = function (blocks) {
const matchTopIds = new Set();
blocks.forEach((block) => {
block.getSvgRoot()?.classList.add("ws-search-match");
let top = block;
while (top.getSurroundParent()) top = top.getSurroundParent();
matchTopIds.add(top.id);
});
workspace.getTopBlocks(false).forEach((block) => {
if (!matchTopIds.has(block.id)) {
block.getSvgRoot()?.classList.add("ws-search-fade");
}
});
};
workspaceSearch.unhighlightSearchGroup = function (blocks) {
blocks.forEach((block) => block.getSvgRoot()?.classList.remove("ws-search-match"));
workspace.getTopBlocks(false).forEach((block) => {
block.getSvgRoot()?.classList.remove("ws-search-fade");
});
};
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);
}
};
workspaceSearch.unhighlightCurrentSelection = function (block) {
block.getSvgRoot()?.classList.remove("ws-search-current");
};

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

Expand Down
113 changes: 39 additions & 74 deletions style/blockly.css
Original file line number Diff line number Diff line change
Expand Up @@ -198,9 +198,6 @@ textarea.blocklyCommentText.blocklyTextarea.blocklyText {
}

body[data-theme="contrast"] {
.blocklyWidgetDiv .blocklyMenuItemContent {
color: black !important;
}
.blocklyField text.blocklyText.blocklyFieldText {
fill: black !important;
}
Expand Down Expand Up @@ -241,9 +238,6 @@ body[data-theme="low-vision"] {
}
}

textarea.blocklyCommentText.blocklyTextarea.blocklyText {
color: black;
}
/* Search Highlight Styles */
.blockly-ws-search {
background: var(--color-bg);
Expand All @@ -256,12 +250,36 @@ textarea.blocklyCommentText.blocklyTextarea.blocklyText {
z-index: 70;
}

path.blocklyPath.blockly-ws-search-highlight {
fill: var(--color-search-highlight);
/* Fade top-level blocks that contain no search matches */
#blocklyDiv.blockly-search-active .ws-search-fade {
opacity: 0.4;
transition: opacity 0.15s ease;
}

path.blocklyPath.blockly-ws-search-highlight.blockly-ws-search-current {
fill: var(--color-border-highlight);
/* Non-current matches get a pale yellow background */
#blocklyDiv.blockly-search-active
.ws-search-match:not(.ws-search-current)
> path.blocklyPath {
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 {
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;
}

@media (min-width: 769px) {
Expand Down Expand Up @@ -418,24 +436,19 @@ path.blocklyPath.blockly-ws-search-highlight.blockly-ws-search-current {
cursor: pointer !important;
}

/* Search Highlight Styles */
.blockly-ws-search {
background: var(--color-bg);
margin-top: 5px;
border: solid var(--color-border-highlight) 4px;
box-shadow: 0px 10px 20px var(--color-shadow);
justify-content: center;
padding: 0.25em;
position: absolute;
z-index: 70;
}

path.blocklyPath.blockly-ws-search-highlight {
fill: var(--color-search-highlight);
[data-theme="dark"] .blockly-ws-search button,
[data-theme="dark-contrast"] .blockly-ws-search button,
[data-theme="low-vision"] .blockly-ws-search button,
[data-theme="contrast"] .blockly-ws-search button {
filter: invert(1);
}

path.blocklyPath.blockly-ws-search-highlight.blockly-ws-search-current {
fill: var(--color-border-highlight);
[data-theme="dark"] .blockly-ws-search button:focus,
[data-theme="dark-contrast"] .blockly-ws-search button:focus,
[data-theme="low-vision"] .blockly-ws-search button:focus,
[data-theme="contrast"] .blockly-ws-search button:focus {
outline: 3px solid #0033cc; /* inverts to #ffcc33 (~#fc3) after filter: invert(1) */
outline-offset: 2px;
}

/* Responsive Styles */
Expand Down Expand Up @@ -471,16 +484,6 @@ path.blocklyPath.blockly-ws-search-highlight.blockly-ws-search-current {
stroke-width: 2.5px !important;
}

/* Toolbox category selection outline */
.blocklyToolboxCategoryContainer[aria-selected="true"][aria-level="1"]
> .blocklyToolboxCategory,
.blocklyToolboxCategoryContainer[aria-selected="true"][aria-level="2"]
> .blocklyToolboxCategory {
outline: 2px solid var(--color-outline-focus);
outline-offset: -2px;
border-radius: 4px;
}

/* 2. Default item text color */
.blocklyDropDownDiv .goog-menuitem-content,
.blocklyWidgetDiv .goog-menuitem-content,
Expand Down Expand Up @@ -575,23 +578,6 @@ body[data-theme="dark"] .blocklyTreeLabel {
outline: none !important;
}

.blocklyToolboxCategoryContainer[aria-selected="true"][aria-level="1"]
> .blocklyToolboxCategory {
outline: 2px solid #fc3;
outline-offset: -2px;
border-radius: 4px;
}

/* Add custom selection outline for both level 1 and 2 categories */
.blocklyToolboxCategoryContainer[aria-selected="true"][aria-level="1"]
> .blocklyToolboxCategory,
.blocklyToolboxCategoryContainer[aria-selected="true"][aria-level="2"]
> .blocklyToolboxCategory {
outline: 2px solid #fc3;
outline-offset: -2px;
border-radius: 4px;
}

[data-theme="contrast"] .blocklyText {
fill: white !important;
}
Expand Down Expand Up @@ -784,22 +770,6 @@ body[data-theme="low-vision"]
}
}

.blocklyToolboxCategoryContainer[aria-selected="true"][aria-level="1"]
> .blocklyToolboxCategory {
outline: 2px solid #fc3;
outline-offset: -2px;
border-radius: 4px;
}

.blocklyToolboxCategoryContainer[aria-selected="true"][aria-level="1"]
> .blocklyToolboxCategory,
.blocklyToolboxCategoryContainer[aria-selected="true"][aria-level="2"]
> .blocklyToolboxCategory {
outline: 2px solid #fc3;
outline-offset: -2px;
border-radius: 4px;
}

/* Keyboard focus for image BUTTON fields only (e.g. plus/minus/toggle icons) */
.blocklyKeyboardNavigation .blocklyActiveFocus.blocklyImageField {
outline: 5px solid var(--block-outline-focus);
Expand Down Expand Up @@ -956,11 +926,6 @@ body[data-theme="low-vision"]
stroke-width: 2px !important;
}

/* Wrap long lines inside the workspace-comment editor */
textarea.blocklyCommentText.blocklyTextarea.blocklyText {
color: black;
}

/* Keep block comment editor constrained to its bubble */
.blocklyCommentForeignObject > body.blocklyMinimalBody,
.blocklyCommentForeignObject textarea.blocklyCommentText {
Expand Down
Loading