diff --git a/tools/nano-tester/.gitignore b/tools/nano-tester/.gitignore new file mode 100644 index 0000000000..c2658d7d1b --- /dev/null +++ b/tools/nano-tester/.gitignore @@ -0,0 +1 @@ +node_modules/ diff --git a/tools/nano-tester/README.md b/tools/nano-tester/README.md new file mode 100644 index 0000000000..8c01aa326b --- /dev/null +++ b/tools/nano-tester/README.md @@ -0,0 +1,12 @@ +# NanoUI Template Tester +A simple utility for previewing how NanoUI templates will look out of game, useful for rapid development cycles. + +## Setup +- Make sure you have Node.js ( https://nodejs.org/ ) installed. +- Run `npm install` to install dependencies +- Edit `index.js` to change the configuration to use the template you want to preview. +- Edit `initialData.json` to contain the initial data that will be generated by your object's `ui_interact` proc. +- Run `node index.js` and then connect at http://localhost:8000/ + +## While Running +- You can update your template files, nano CSS or initialData.json at any time while the server is running. diff --git a/tools/nano-tester/index.html b/tools/nano-tester/index.html new file mode 100644 index 0000000000..70f5dfecd2 --- /dev/null +++ b/tools/nano-tester/index.html @@ -0,0 +1,45 @@ + + + + + + + + + + + + + + + + + + + + +
+
+ + + \ No newline at end of file diff --git a/tools/nano-tester/index.js b/tools/nano-tester/index.js new file mode 100644 index 0000000000..53eb6f3576 --- /dev/null +++ b/tools/nano-tester/index.js @@ -0,0 +1,105 @@ +//'use strict' +// +// Mini webserver for testing NanoUI templates +// +const fs = require('fs'); +const http = require('http'); +const mime = require('mime'); +const path = require('path'); +const url = require('url'); +const dot = require('dot'); + +// Configuration constants +var config = { + "port": 8000, // Port to listen on + "dir": "../../nano", // Path to SS13 nano folder +}; + +// Choose your templates here. Hint: You'll probably never change layout, main is the one you want. +var templateData = { + layout: "layout_default.tmpl", + main: "smes.tmpl" +}; + +// In BYOND everything is sent to the client's byond cache, so its all in one flat directory. +// On the actual filesystem here of course, its in subfolders. To emulate that we decide what +// folder to look in based on file extention. +const extFolderMapping = { + ".png": path.join(process.cwd(), config.dir, "images"), + ".jpg": path.join(process.cwd(), config.dir, "images"), + ".jpeg": path.join(process.cwd(), config.dir, "images"), + ".gif": path.join(process.cwd(), config.dir, "images"), + ".js": path.join(process.cwd(), config.dir, "js"), + ".css": path.join(process.cwd(), config.dir, "css"), + ".tmpl": path.join(process.cwd(), config.dir, "templates") +}; + +// Read the shipped index.html as a doT template. +var genIndexHtml = dot.template(fs.readFileSync('index.html', 'utf8')); + +// the main thing +var server = http.createServer( function(request, response) { + + // extract the pathname from the request URL + var pathname = url.parse(request.url).pathname; + + // Exception for front page + if (pathname === '/') { + let initialData = JSON.parse(fs.readFileSync('initialData.json', 'utf8')); + response.writeHead(200, {"Content-Type": "text/html"}); + response.write(genIndexHtml({ + initialDataJson: JSON.stringify(initialData), + templateDataJson: JSON.stringify(templateData) + })); + response.end(); + return; + } + + // Map URL path to physical path. + // First check our folder mapping + var filename; + var fileExt = path.extname(pathname); + if (fileExt in extFolderMapping) { + filename = path.join(extFolderMapping[fileExt], path.basename(pathname)); + } else { + // Otherwise fall back to just a relative path to our base dir. + filename = path.join(process.cwd(), config.dir, pathname); + } + + // console.log("Trying to serve ", pathname, " from ", filename); + + // Does this path exist? + fs.exists(filename, function(gotPath) { + // no, bail out + if (!gotPath) { + console.warn("Path: %s File: %s NOT FOUND", pathname, filename); + response.writeHead(404, {"Content-Type": "text/plain"}); + response.write("404 Not Found"); + response.end(); + return; + } + + // still here? filename is good + // look up the mime type by file extension + response.writeHead(200, {'Content-Type': mime.getType(filename)}); + + // read and pass the file as a stream. Not really sure if this is better, + // but it feels less block-ish than reading the whole file + // and we get to do awesome things with listeners + fs.createReadStream(filename, { + 'flags': 'r', + 'encoding': 'binary', + 'mode': 0x3146, // 0666 + 'bufferSize': 4 * 1024 + }).addListener( "data", function(chunk) { + response.write(chunk, 'binary'); + }).addListener( "close",function() { + response.end(); + }); + + }); +}); + +// fire it up +server.listen(config.port); +console.log("Listening on port %d", config.port); diff --git a/tools/nano-tester/initialData.json b/tools/nano-tester/initialData.json new file mode 100644 index 0000000000..9996c4dd51 --- /dev/null +++ b/tools/nano-tester/initialData.json @@ -0,0 +1,20 @@ +{ + "config": { + "title": "SMES" + }, + "data": { + "nameTag": "Test SMES", + "storedCapacity": 50, + "storedCapacityAbs": 400, + "storedCapacityMax": 800, + "charging": 1, + "chargeMode": 1, + "chargeLevel": 100, + "chargeMax": 250, + "chargeLoad": 0, + "outputOnline": 1, + "outputLevel": 75, + "outputMax": 250, + "outputLoad": 45 + } +} diff --git a/tools/nano-tester/package.json b/tools/nano-tester/package.json new file mode 100644 index 0000000000..f961d9ff87 --- /dev/null +++ b/tools/nano-tester/package.json @@ -0,0 +1,19 @@ +{ + "name": "nano-tester", + "version": "1.0.0", + "description": "Test NanoUI Templates", + "main": "index.js", + "dependencies": { + "dot": "^1.1.2", + "mime": "^2.2.0" + }, + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1" + }, + "repository": { + "type": "git", + "url": "https://github.com/VOREStation/VOREStation.git" + }, + "author": "Leshana", + "license": "AGPL-3.0" +}