Skip to content

Commit

Permalink
Fix mit-cml#3335: Detect and handle unavailable extensions in dragged…
Browse files Browse the repository at this point in the history
… PNGs
  • Loading branch information
d1vyanshu-kumar committed Jan 23, 2025
1 parent af582d2 commit 95b6bec
Showing 1 changed file with 81 additions and 0 deletions.
81 changes: 81 additions & 0 deletions appinventor/blocklyeditor/src/exportBlocksImage.js
Original file line number Diff line number Diff line change
Expand Up @@ -517,6 +517,75 @@ Blockly.exportBlockAsPng = function(block) {
});
};

/**
* Extracts the block types from the given XML.
* @param {Document} xml - The XML document containing blocks.
* @returns {Array<string>} An array of block types.
*/
function extractBlockTypes(xml) {
var blockTypes = [];
var blocks = xml.getElementsByTagName('block');
for (var i = 0; i < blocks.length; i++) {
var mutation = blocks[i].getElementsByTagName('mutation')[0];
if (mutation) {
var componentType = mutation.getAttribute('component_type');
if (componentType) {
blockTypes.push(componentType);
}
}
}
return blockTypes;
}

/**
* Validates the block types against the component database in the workspace.
* @param {Array<string>} blockTypes - The block types to validate.
* @param {Blockly.WorkspaceSvg} workspace - The workspace containing the component database.
* @returns {Array<string>} An array of missing component types.
*/
function validateBlockTypes(blockTypes, workspace) {
if (!blockTypes || blockTypes.length === 0) {
console.warn('No block types provided for validation.');
return [];
}

var componentDb = workspace.getComponentDatabase();
if (!componentDb) {
console.error('Component database is not available.');
return [];
}

var missingExtensions = [];
for (var i = 0; i < blockTypes.length; i++) {
var typeDescriptor = componentDb.getType(blockTypes[i]);
if (!typeDescriptor || !typeDescriptor.componentInfo || typeDescriptor.componentInfo.name !== blockTypes[i]) {
missingExtensions.push(blockTypes[i]);
}
}

if (missingExtensions.length > 0) {
console.warn('Missing component types:', missingExtensions.join(', '));
}
return missingExtensions;
}

/**
* Displays a dialog showing the missing extensions.
* @param {Array<string>} missingExtensions - The missing component types.
*/
function showMissingExtensionDialog(missingExtensions) {
// Filter out undefined or null values
missingExtensions = missingExtensions.filter(function(extension) {
return extension !== undefined && extension !== null;
});

if (missingExtensions.length > 0) {
var message = 'This image references the following blocks which require extensions that are not present in the project:\n\n';
message += missingExtensions.join('\n');
alert(message);
}
}

/**
* Imports a block from a PNG file if the code chunk is present.
* @param {!Blockly.WorkspaceSvg} workspace the target workspace for the block
Expand All @@ -529,6 +598,18 @@ Blockly.importPngAsBlock = function(workspace, xy, png) {
if (xmlChunk) {
var xmlText = new TextDecoder().decode(xmlChunk.data);
var xml = /** @type {!Element} */ (Blockly.utils.xml.textToDom(xmlText));
if (!xml) {
console.error('Failed to parse XML from PNG.');
return;
}
var blockTypes = extractBlockTypes(xml);

var missingExtensions = validateBlockTypes(blockTypes, workspace);
if (missingExtensions.length > 0) {
showMissingExtensionDialog(missingExtensions);
return;
}

xml = xml.firstElementChild;
var block = /** @type {Blockly.BlockSvg} */ (Blockly.Xml.domToBlock(xml, workspace));
block.moveBy(xy.x, xy.y);
Expand Down

0 comments on commit 95b6bec

Please sign in to comment.