diff --git a/addons/custom-block-shape/update-all-blocks.js b/addons/custom-block-shape/update-all-blocks.js deleted file mode 100644 index 710b164009..0000000000 --- a/addons/custom-block-shape/update-all-blocks.js +++ /dev/null @@ -1,18 +0,0 @@ -export function updateAllBlocks(vm) { - const workspace = window.Blockly.getMainWorkspace(); - if (workspace) { - if (vm.editingTarget) { - vm.emitWorkspaceUpdate(); - } - const flyout = workspace.getFlyout(); - if (flyout) { - const flyoutWorkspace = flyout.getWorkspace(); - window.Blockly.Xml.clearWorkspaceAndLoadFromXml( - window.Blockly.Xml.workspaceToDom(flyoutWorkspace), - flyoutWorkspace - ); - workspace.getToolbox().refreshSelection(); - workspace.toolboxRefreshEnabled_ = true; - } - } -} diff --git a/addons/custom-block-shape/userscript.js b/addons/custom-block-shape/userscript.js index 5e7dd9d542..4a1e734d59 100644 --- a/addons/custom-block-shape/userscript.js +++ b/addons/custom-block-shape/userscript.js @@ -1,5 +1,3 @@ -import { updateAllBlocks } from "./update-all-blocks.js"; - export default async function ({ addon, console }) { var BlocklyInstance = await addon.tab.traps.getBlockly(); @@ -9,6 +7,22 @@ export default async function ({ addon, console }) { const { GRID_UNIT } = BlockSvg; + function updateAllBlocks() { + const workspace = Blockly.getMainWorkspace(); + if (workspace) { + if (vm.editingTarget) { + vm.emitWorkspaceUpdate(); + } + const flyout = workspace.getFlyout(); + if (flyout) { + const flyoutWorkspace = flyout.getWorkspace(); + Blockly.Xml.clearWorkspaceAndLoadFromXml(Blockly.Xml.workspaceToDom(flyoutWorkspace), flyoutWorkspace); + workspace.getToolbox().refreshSelection(); + workspace.toolboxRefreshEnabled_ = true; + } + } + } + function applyChanges( paddingSize = addon.settings.get("paddingSize"), cornerSize = addon.settings.get("cornerSize"), @@ -238,7 +252,7 @@ export default async function ({ addon, console }) { function applyAndUpdate(...args) { applyChanges(...args); - updateAllBlocks(vm); + updateAllBlocks(); } addon.settings.addEventListener("change", () => applyAndUpdate()); diff --git a/addons/custom-block-text/addon.json b/addons/custom-block-text/addon.json index 887b148b8d..8bb9d44463 100644 --- a/addons/custom-block-text/addon.json +++ b/addons/custom-block-text/addon.json @@ -1,6 +1,6 @@ { "name": "Customizable block text style", - "description": "Allows you to make a few adjustments to block text to make it easier to read.", + "description": "Changes the thickness of the text on blocks and optionally adds a text shadow.", "tags": ["editor", "codeEditor", "featured"], "credits": [ { @@ -10,16 +10,18 @@ { "name": "_nix", "link": "https://github.com/towerofnix" - }, - { - "name": "DNin01", - "link": "https://github.com/DNin01" } ], - "userscripts": [ + "userstyles": [ + { + "url": "text-bold.css", + "matches": ["projects"], + "if": { "settings": { "bold": true } } + }, { - "url": "userscript.js", - "matches": ["projects"] + "url": "text-shadow.css", + "matches": ["projects"], + "if": { "settings": { "shadow": true } } } ], "settings": [ @@ -34,22 +36,11 @@ "id": "shadow", "type": "boolean", "default": false - }, - { - "name": "Text size (%)", - "id": "size", - "type": "integer", - "min": 75, - "max": 200, - "default": 100 } ], "dynamicEnable": true, "dynamicDisable": true, + "updateUserstylesOnSettingsChange": true, "versionAdded": "1.24.0", - "latestUpdate": { - "version": "1.33.0", - "newSettings": ["size"] - }, "enabledByDefault": false } diff --git a/addons/custom-block-text/text-bold.css b/addons/custom-block-text/text-bold.css new file mode 100644 index 0000000000..1dd8abbc51 --- /dev/null +++ b/addons/custom-block-text/text-bold.css @@ -0,0 +1,4 @@ +.blocklyText, +.blocklyHtmlInput { + font-weight: bold; +} diff --git a/addons/custom-block-text/text-shadow.css b/addons/custom-block-text/text-shadow.css new file mode 100644 index 0000000000..5b1999c0d0 --- /dev/null +++ b/addons/custom-block-text/text-shadow.css @@ -0,0 +1,5 @@ +/** Makes block text a little easier to read. **/ +.blocklyDraggable > .blocklyText, +.blocklyDraggable > g > text { + text-shadow: 1px 1px 0 rgba(0, 0, 0, 0.4); +} diff --git a/addons/custom-block-text/userscript.js b/addons/custom-block-text/userscript.js deleted file mode 100644 index a7f6266cff..0000000000 --- a/addons/custom-block-text/userscript.js +++ /dev/null @@ -1,93 +0,0 @@ -import { updateAllBlocks } from "../custom-block-shape/update-all-blocks.js"; -import { clearTextWidthCache } from "../middle-click-popup/module.js"; - -export default async function ({ addon, console }) { - let currentTextSize = 100; - - const vm = addon.tab.traps.vm; - const blocklyInstance = await addon.tab.traps.getBlockly(); - - // Handling the CSS from here instead of a userstyle is much more stable, as - // there's no code outside of this addon dynamically toggling the styles. - // This way, we can clearly control the execution order of style operations. - // For example, we always want to call updateAllBlocks() after the styles - // were updated according to the user's settings, not before. - const fontSizeCss = document.createElement("style"); - fontSizeCss.textContent = ` - .blocklyText, - .blocklyHtmlInput { - font-size: calc(var(--customBlockText-sizeSetting) * 0.12pt) !important; - }`; - fontSizeCss.disabled = true; - document.head.appendChild(fontSizeCss); - // - const boldCss = document.createElement("style"); - boldCss.textContent = ` - .blocklyText, - .blocklyHtmlInput { - font-weight: bold; - }`; - boldCss.disabled = true; - document.head.appendChild(boldCss); - // - const textShadowCss = document.createElement("style"); - textShadowCss.textContent = ` - .blocklyDraggable > .blocklyText, - .blocklyDraggable > g > text { - text-shadow: 1px 1px 0 rgba(0, 0, 0, 0.4); - }`; - textShadowCss.disabled = true; - document.head.appendChild(textShadowCss); - - const updateBlockly = () => { - blocklyInstance.Field.cacheWidths_ = {}; // Clear text width cache - // If font size has changed, middle click popup needs to clear it's cache too - clearTextWidthCache(); - - updateAllBlocks(vm); - }; - - const setFontSize = (wantedSize) => { - if (wantedSize !== 100) document.documentElement.style.setProperty("--customBlockText-sizeSetting", wantedSize); - - if (wantedSize === 100) { - fontSizeCss.disabled = true; - currentTextSize = 100; - return; - } else if (wantedSize === currentTextSize) return; - - currentTextSize = wantedSize; - fontSizeCss.disabled = false; - }; - const setBold = (bool) => { - boldCss.disabled = !bool; - }; - const setTextShadow = (bool) => { - textShadowCss.disabled = !bool; - }; - - addon.settings.addEventListener("change", () => { - setFontSize(addon.settings.get("size")); - setBold(addon.settings.get("bold")); - setTextShadow(addon.settings.get("shadow")); - updateBlockly(); - }); - - addon.self.addEventListener("disabled", () => { - setFontSize(100); - setBold(false); - setTextShadow(false); - updateBlockly(); - }); - addon.self.addEventListener("reenabled", () => { - setFontSize(addon.settings.get("size")); - setBold(addon.settings.get("bold")); - setTextShadow(addon.settings.get("shadow")); - updateBlockly(); - }); - - setFontSize(addon.settings.get("size")); - setBold(addon.settings.get("bold")); - setTextShadow(addon.settings.get("shadow")); - updateBlockly(); -} diff --git a/addons/middle-click-popup/BlockRenderer.js b/addons/middle-click-popup/BlockRenderer.js index 579708e2db..5b06925285 100644 --- a/addons/middle-click-popup/BlockRenderer.js +++ b/addons/middle-click-popup/BlockRenderer.js @@ -5,7 +5,6 @@ */ import { BlockShape, BlockInstance, BlockInputEnum, BlockInputBoolean, BlockInputBlock } from "./BlockTypeInfo.js"; -import { getTextWidth } from "./module.js"; const SVG_NS = "http://www.w3.org/2000/svg"; @@ -177,6 +176,26 @@ function createTextComponent(text, fillVar, container) { return new BlockComponent(textElement, 0, getTextWidth(textElement)); } +const textWidthCache = new Map(); +const textWidthCacheSize = 1000; + +/** + * Gets the width of an svg text element, with caching. + * @param {SVGTextElement} textElement + */ +function getTextWidth(textElement) { + let string = textElement.innerHTML; + if (string.length === 0) return 0; + let width = textWidthCache.get(string); + if (width) return width; + width = textElement.getBoundingClientRect().width; + textWidthCache.set(string, width); + if (textWidthCache.size > textWidthCacheSize) { + textWidthCache.delete(textWidthCache.keys().next()); + } + return width; +} + /** * Creates a DOM element to hold all the contents of a block. * A block could be the top level block, or it could be a block like (() + ()) that's inside diff --git a/addons/middle-click-popup/module.js b/addons/middle-click-popup/module.js deleted file mode 100644 index 91ad01fa06..0000000000 --- a/addons/middle-click-popup/module.js +++ /dev/null @@ -1,37 +0,0 @@ -const textWidthCache = new Map(); -const textWidthCacheSize = 1000; - -const eventTarget = new EventTarget(); -const eventClearTextCache = "clearTextCache"; - -/** - * Gets the width of an svg text element, with caching. - * @param {SVGTextElement} textElement - */ -export function getTextWidth(textElement) { - let string = textElement.innerHTML; - if (string.length === 0) return 0; - let width = textWidthCache.get(string); - if (width) return width; - width = textElement.getBoundingClientRect().width; - textWidthCache.set(string, width); - if (textWidthCache.size > textWidthCacheSize) { - textWidthCache.delete(textWidthCache.keys().next()); - } - return width; -} - -/** - * Clears the text width cache of the middle click popup. - */ -export function clearTextWidthCache() { - textWidthCache.clear(); - eventTarget.dispatchEvent(new CustomEvent(eventClearTextCache)); -} - -/** - * @param {() => void} func - */ -export function onClearTextWidthCache(func) { - eventTarget.addEventListener(eventClearTextCache, func); -} diff --git a/addons/middle-click-popup/userscript.js b/addons/middle-click-popup/userscript.js index a0a46d45dc..f7bfb191da 100644 --- a/addons/middle-click-popup/userscript.js +++ b/addons/middle-click-popup/userscript.js @@ -3,7 +3,6 @@ import WorkspaceQuerier, { QueryResult } from "./WorkspaceQuerier.js"; import renderBlock, { BlockComponent, getBlockHeight } from "./BlockRenderer.js"; import { BlockInstance, BlockShape, BlockTypeInfo } from "./BlockTypeInfo.js"; -import { onClearTextWidthCache } from "./module.js"; export default async function ({ addon, msg, console }) { const Blockly = await addon.tab.traps.getBlockly(); @@ -70,8 +69,6 @@ export default async function ({ addon, msg, console }) { mousePosition = { x: e.clientX, y: e.clientY }; }); - onClearTextWidthCache(closePopup); - /** * @typedef ResultPreview * @property {BlockInstance} block