Spaces:
Runtime error
Runtime error
File size: 4,882 Bytes
8fd7a1d |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 |
import {BLOCKS_THREE} from '.';
const getBlockIconURI = extensionIcons => {
if (!extensionIcons) return null;
return extensionIcons.blockIconURI || extensionIcons.menuIconURI;
};
const getCategoryIconURI = extensionIcons => {
if (!extensionIcons) return null;
return extensionIcons.menuIconURI || extensionIcons.blockIconURI;
};
// scratch-blocks colours has a pen property that scratch-gui uses for all extensions
const getExtensionColors = theme => theme.getBlockColors().pen;
const DEFAULT_EXTENSION_PRIMARY = '#0fbd8c';
/**
* Applies extension color theme to categories.
* No changes are applied if called with the default theme, allowing extensions to provide their own colors.
* These colors are not seen if the category provides a blockIconURI.
* @param {Array.<object>} dynamicBlockXML - XML for each category of extension blocks, returned from getBlocksXML
* in the vm runtime.
* @param {Theme} theme - Theme name
* @returns {Array.<object>} Dynamic block XML updated with colors.
*/
const injectExtensionCategoryTheme = (dynamicBlockXML, theme) => {
// Minor optimization -- don't do anything at all for the default theme.
if (theme.blocks === BLOCKS_THREE) return dynamicBlockXML;
const extensionColors = getExtensionColors(theme);
const extensionIcons = theme.getExtensions();
const parser = new DOMParser();
const serializer = new XMLSerializer();
return dynamicBlockXML.map(extension => {
const dom = parser.parseFromString(extension.xml, 'text/xml');
const primaryColor = dom.documentElement.getAttribute('colour');
const usesCustomColors = primaryColor.toLowerCase() !== DEFAULT_EXTENSION_PRIMARY;
if (usesCustomColors) {
const converters = theme.getCustomExtensionColors();
dom.documentElement.setAttribute('colour', converters.categoryIconBackground(primaryColor));
dom.documentElement.setAttribute('secondaryColour', converters.categoryIconBorder(primaryColor));
} else {
dom.documentElement.setAttribute('colour', extensionColors.primary);
// Note: the category's secondaryColour matches up with the blocks' tertiary color,
// both used for border color.
dom.documentElement.setAttribute('secondaryColour', extensionColors.tertiary);
}
const categoryIconURI = getCategoryIconURI(extensionIcons[extension.id]);
if (categoryIconURI) {
dom.documentElement.setAttribute('iconURI', categoryIconURI);
}
return {
...extension,
xml: serializer.serializeToString(dom)
};
});
};
const injectBlockIcons = (blockInfoJson, theme) => {
// Block icons are the first element of `args0`
if (!blockInfoJson.args0 || blockInfoJson.args0.length < 1 ||
blockInfoJson.args0[0].type !== 'field_image') return blockInfoJson;
const extensionIcons = theme.getExtensions();
const extensionId = blockInfoJson.type.substring(0, blockInfoJson.type.indexOf('_'));
const blockIconURI = getBlockIconURI(extensionIcons[extensionId]);
if (!blockIconURI) return blockInfoJson;
return {
...blockInfoJson,
args0: blockInfoJson.args0.map((value, index) => {
if (index !== 0) return value;
return {
...value,
src: blockIconURI
};
})
};
};
/**
* Applies extension color theme to static block json.
* No changes are applied if called with the default theme, allowing extensions to provide their own colors.
* @param {object} blockInfoJson - Static block json
* @param {Theme} theme - Theme name
* @returns {object} Block info json with updated colors. The original blockInfoJson is not modified.
*/
const injectExtensionBlockTheme = (blockInfoJson, theme) => {
// Minor optimization -- don't do anything at all for the default theme.
if (theme.blocks === BLOCKS_THREE) return blockInfoJson;
if (!blockInfoJson.extensions?.includes('default_extension_colors')) {
const converters = theme.getCustomExtensionColors();
return {
...blockInfoJson,
colour: converters.primary(blockInfoJson.colour),
colourSecondary: converters.secondary(blockInfoJson.colour),
colourTertiary: converters.tertiary(blockInfoJson.colour),
colourQuaternary: converters.quaternary(blockInfoJson.colour)
};
}
const extensionColors = getExtensionColors(theme);
return {
...injectBlockIcons(blockInfoJson, theme),
colour: extensionColors.primary,
colourSecondary: extensionColors.secondary,
colourTertiary: extensionColors.tertiary,
colourQuaternary: extensionColors.quaternary
};
};
export {
injectExtensionBlockTheme,
injectExtensionCategoryTheme
};
|