mirror of
https://github.com/damp11113-software/ccIDE.git
synced 2025-04-28 06:58:13 +00:00
237 lines
9.6 KiB
JavaScript
237 lines
9.6 KiB
JavaScript
const fs = require('fs');
|
|
const path = require('path');
|
|
const { DOMParser, XMLSerializer } = require('xmldom');
|
|
|
|
const peripheralsfolder = path.join(__dirname, "../blocks");
|
|
|
|
const fallbackImagePath = path.join(__dirname, '..', 'assets', 'noimagefallback.png'); // Path to fallback image
|
|
|
|
|
|
const defineicon = {
|
|
computer: {
|
|
basic: path.join(__dirname, '..', 'assets', 'basic_computer.png'),
|
|
adv: path.join(__dirname, '..', 'assets', 'adv_computer.png'),
|
|
command: path.join(__dirname, '..', 'assets', 'command_computer.png'),
|
|
pocket: path.join(__dirname, '..', 'assets', 'pocket_computer.png'),
|
|
advpocket: path.join(__dirname, '..', 'assets', 'adv_pocket_computer.png'),
|
|
turtle: path.join(__dirname, '..', 'assets', 'turtle.png'),
|
|
advturtle: path.join(__dirname, '..', 'assets', 'adv_turtle.png')
|
|
},
|
|
peripheral: path.join(__dirname, '..', 'assets', 'peripheral.png'),
|
|
library: path.join(__dirname, '..', 'assets', 'library.png'),
|
|
networkreq: path.join(__dirname, '..', 'assets', 'network-require.png')
|
|
}
|
|
|
|
function mergeXml(xml1, xml2) {
|
|
const parser = new DOMParser();
|
|
const serializer = new XMLSerializer();
|
|
|
|
const doc1 = parser.parseFromString(xml1, 'text/xml');
|
|
const doc2 = parser.parseFromString(xml2, 'text/xml');
|
|
|
|
const root1 = doc1.documentElement;
|
|
const children2 = doc2.documentElement.childNodes;
|
|
|
|
// Iterate through children2 and append each node to root1
|
|
for (let i = 0; i < children2.length; i++) {
|
|
root1.appendChild(children2[i].cloneNode(true));
|
|
}
|
|
|
|
const mergedXml = serializer.serializeToString(doc1);
|
|
return mergedXml;
|
|
}
|
|
|
|
function loadperipheral(workspace, currenttoolbar, peripherals) {
|
|
console.log(`Importing ${peripherals} blocks`)
|
|
|
|
const filePath = path.join(peripheralsfolder, peripherals);
|
|
const jsonfilePath = path.join(filePath, "block_design.json");
|
|
const xmlfilePath = path.join(filePath, "toolbox.xml");
|
|
const generatorfilePath = path.join(filePath, "generator.js"); // Path to generator.js
|
|
|
|
// Load generator.js
|
|
// Load blocks from block_design.json
|
|
fs.readFile(jsonfilePath, 'utf-8', (err, data) => {
|
|
if (err) {
|
|
console.error('Error loading JSON file:', err);
|
|
return;
|
|
}
|
|
try {
|
|
const blocksJson = JSON.parse(data);
|
|
for (const blockId in blocksJson) {
|
|
if (blocksJson.hasOwnProperty(blockId)) {
|
|
Blockly.Blocks[blockId] = {
|
|
init: function() {
|
|
this.jsonInit(blocksJson[blockId]);
|
|
}
|
|
};
|
|
}
|
|
}
|
|
} catch (e) {
|
|
document.getElementById('statusMessage').textContent = 'Error parsing JSON file: ' + e;
|
|
return;
|
|
}
|
|
});
|
|
|
|
// Load and merge new toolbox XML
|
|
const toolbar = fs.readFileSync(xmlfilePath, 'utf8');
|
|
const newxml = mergeXml(currenttoolbar, toolbar);
|
|
|
|
workspace.updateToolbox(newxml);
|
|
|
|
document.getElementById('statusMessage').textContent = `Loaded ${peripherals}`;
|
|
|
|
require(generatorfilePath); // This will execute generator.js if it's a Node.js module
|
|
|
|
console.log(`Loaded ${peripherals} blocks`)
|
|
|
|
return newxml;
|
|
}
|
|
|
|
function extractFolderName(path) {
|
|
// Normalize path separators to handle both Windows and Unix-style paths
|
|
const normalizedPath = path.replace(/[\\\/]/g, '/');
|
|
// Split by '/' to get path segments
|
|
const parts = normalizedPath.split('/');
|
|
// Filter out empty parts and get the last segment
|
|
const folderName = parts.filter(part => part.trim() !== '').pop();
|
|
return folderName;
|
|
}
|
|
|
|
function fileExists(filePath) {
|
|
try {
|
|
return fs.existsSync(filePath);
|
|
} catch (err) {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
function addimageiconinfo(div, src, tiptool) {
|
|
const img = document.createElement('img');
|
|
img.src = src
|
|
img.classList.add("libimageicon");
|
|
img.setAttribute('data-bs-toggle', "tooltip");
|
|
img.setAttribute('data-bs-placement', "bottom");
|
|
img.setAttribute('data-bs-title', tiptool);
|
|
div.appendChild(img);
|
|
console.log(`added image ${src}`);
|
|
}
|
|
|
|
function scanindex() {
|
|
let foundedpackages = 0;
|
|
document.getElementById('statusMessage').textContent = "Scanning Packages...";
|
|
// clear all item in libcontainer
|
|
document.getElementById('libcontainer').innerHTML = "";
|
|
|
|
const files = fs.readdirSync(peripheralsfolder);
|
|
|
|
// Iterate through files and directories
|
|
files.forEach(file => {
|
|
const filePath = path.join(peripheralsfolder, file);
|
|
const stat = fs.statSync(filePath);
|
|
|
|
if (stat.isDirectory()) {
|
|
// If it's a directory, recursively call scanFolders
|
|
const files = fs.readdirSync(filePath);
|
|
files.forEach(file => {
|
|
if (file === 'index.json') {
|
|
const filePath2 = path.join(filePath, file);
|
|
// If it's a file named index.json, read its contents
|
|
const content = fs.readFileSync(filePath2, 'utf8');
|
|
const jsonData = JSON.parse(content);
|
|
|
|
blockfoldername = extractFolderName(filePath);
|
|
if (!blockfoldername.startsWith("_")) {
|
|
foundedpackages++;
|
|
|
|
// create item in list
|
|
const imagePath = path.join(filePath, "icon.png");
|
|
|
|
const libraryItem = document.createElement('div');
|
|
libraryItem.classList.add('library-item', 'overflow-auto', 'library-container');
|
|
libraryItem.setAttribute('data-libraryfolder', blockfoldername);
|
|
|
|
// add image
|
|
const img = document.createElement('img');
|
|
img.classList.add('libimage');
|
|
if (fileExists(imagePath)) {
|
|
img.src = imagePath;
|
|
} else {
|
|
img.src = fallbackImagePath;
|
|
}
|
|
libraryItem.appendChild(img);
|
|
|
|
// Create the library details container
|
|
const libraryDetails = document.createElement('div');
|
|
libraryDetails.classList.add('library-details');
|
|
|
|
// Create the title element
|
|
const title = document.createElement('h3');
|
|
title.textContent = jsonData.name + ` [v${jsonData.version} by ${jsonData.author}]`;
|
|
libraryDetails.appendChild(title);
|
|
|
|
// Create the description element
|
|
const description = document.createElement('p');
|
|
description.innerHTML = jsonData.description;
|
|
libraryDetails.appendChild(description);
|
|
|
|
if (jsonData.design_for_computer.basic) {
|
|
addimageiconinfo(libraryDetails, defineicon.computer.basic, "Basic Computer Supported");
|
|
}
|
|
if (jsonData.design_for_computer.adv) {
|
|
addimageiconinfo(libraryDetails, defineicon.computer.adv, "Advanced Computer Supported");
|
|
}
|
|
if (jsonData.design_for_computer.command) {
|
|
addimageiconinfo(libraryDetails, defineicon.computer.command, "Command Computer Supported");
|
|
}
|
|
if (jsonData.design_for_computer.pocket) {
|
|
addimageiconinfo(libraryDetails, defineicon.computer.pocket, "Pocket Computer Supported");
|
|
}
|
|
if (jsonData.design_for_computer.advpocket) {
|
|
addimageiconinfo(libraryDetails, defineicon.computer.advpocket, "Advanced Pocket Computer Supported");
|
|
}
|
|
if (jsonData.design_for_computer.turtle) {
|
|
addimageiconinfo(libraryDetails, defineicon.computer.turtle, "Turtle Supported");
|
|
}
|
|
if (jsonData.design_for_computer.advturtle) {
|
|
addimageiconinfo(libraryDetails, defineicon.computer.advturtle, "Advanced Turtle Supported");
|
|
}
|
|
|
|
// check computer type support
|
|
if (jsonData.peripherals) {
|
|
addimageiconinfo(libraryDetails, defineicon.peripheral, "Peripheral");
|
|
}
|
|
if (jsonData.library) {
|
|
addimageiconinfo(libraryDetails, defineicon.library, "Library");
|
|
}
|
|
if (jsonData.require_network) {
|
|
addimageiconinfo(libraryDetails, defineicon.networkreq, "Require Network");
|
|
}
|
|
|
|
libraryItem.appendChild(libraryDetails);
|
|
document.getElementById('libcontainer').appendChild(libraryItem);
|
|
console.log(`Registered ${blockfoldername} blocks and added to packages managers`)
|
|
}
|
|
}
|
|
|
|
})
|
|
}
|
|
});
|
|
|
|
document.querySelectorAll('.library-item').forEach(item => {
|
|
item.addEventListener('click', () => {
|
|
item.classList.toggle('selected');
|
|
});
|
|
});
|
|
|
|
document.getElementById('statusMessage').textContent = `Founded ${foundedpackages} Packages`;
|
|
setTimeout(() => {
|
|
document.getElementById('statusMessage').textContent = `Ready`;
|
|
}, 1000);
|
|
}
|
|
|
|
|
|
module.exports = {
|
|
loadperipheral,
|
|
scanindex
|
|
} |