mirror of
https://github.com/scratchfoundation/scratch-blocks.git
synced 2025-08-28 22:10:31 -04:00
Changes needed to make headless work.
This commit is contained in:
parent
f0e2c72db5
commit
8977ebf46f
5 changed files with 93 additions and 29 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -5,3 +5,4 @@ npm-debug.log
|
|||
.project
|
||||
*.pyc
|
||||
*.komodoproject
|
||||
node_modules
|
29
app.headless.js
Normal file
29
app.headless.js
Normal file
|
@ -0,0 +1,29 @@
|
|||
// This program is to be used with NodeJS run Blockly headless. It loads
|
||||
// Blockly XML from `input.xml` and outputs python code on `stdout`.
|
||||
|
||||
global.DOMParser = require('xmldom').DOMParser;
|
||||
|
||||
global.Blockly = require('./blockly_uncompressed.js');
|
||||
|
||||
require('./blocks_compressed.js');
|
||||
require('./python_compressed.js');
|
||||
|
||||
var fs = require('fs');
|
||||
|
||||
//the contents of './input.xml' are passed as the `data` parameter
|
||||
fs.readFile('./input.xml', function (err, data) {
|
||||
if (err) throw err;
|
||||
|
||||
var xmlText = data.toString(); //convert the data buffer to a string
|
||||
try {
|
||||
var xml = Blockly.Xml.textToDom(xmlText);
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
return;
|
||||
}
|
||||
// Create a headless workspace.
|
||||
var workspace = new Blockly.Workspace();
|
||||
Blockly.Xml.domToWorkspace(workspace, xml);
|
||||
var code = Blockly.Python.workspaceToCode(workspace);
|
||||
console.log(code);
|
||||
});
|
71
build.py
71
build.py
|
@ -103,30 +103,43 @@ class Gen_uncompressed(threading.Thread):
|
|||
f = open(target_filename, "w")
|
||||
f.write(HEADER)
|
||||
f.write("""
|
||||
// 'this' is 'window' in a browser, or 'global' in node.js.
|
||||
this.BLOCKLY_DIR = (function() {
|
||||
// Find name of current directory.
|
||||
var scripts = document.getElementsByTagName('script');
|
||||
var re = new RegExp('(.+)[\/]blockly_uncompressed\.js$');
|
||||
for (var x = 0, script; script = scripts[x]; x++) {
|
||||
var match = re.exec(script.src);
|
||||
if (match) {
|
||||
return match[1];
|
||||
var isNodeJS = !!(typeof module !== 'undefined' && module.exports);
|
||||
|
||||
if (isNodeJS) {
|
||||
var window = {};
|
||||
require('../closure-library/closure/goog/bootstrap/nodejs')
|
||||
}
|
||||
|
||||
window.BLOCKLY_DIR = (function() {
|
||||
if (!isNodeJS)
|
||||
{
|
||||
// Find name of current directory.
|
||||
var scripts = document.getElementsByTagName('script');
|
||||
var re = new RegExp('(.+)[\/]blockly_uncompressed\.js$');
|
||||
for (var x = 0, script; script = scripts[x]; x++) {
|
||||
var match = re.exec(script.src);
|
||||
if (match) {
|
||||
return match[1];
|
||||
}
|
||||
}
|
||||
alert('Could not detect Blockly\\'s directory name.');
|
||||
}
|
||||
alert('Could not detect Blockly\\'s directory name.');
|
||||
return '';
|
||||
})();
|
||||
|
||||
this.BLOCKLY_BOOT = function() {
|
||||
// Execute after Closure has loaded.
|
||||
if (!this.goog) {
|
||||
alert('Error: Closure not found. Read this:\\n' +
|
||||
'developers.google.com/blockly/hacking/closure');
|
||||
}
|
||||
|
||||
// Build map of all dependencies (used and unused).
|
||||
var dir = this.BLOCKLY_DIR.match(/[^\\/]+$/)[0];
|
||||
window.BLOCKLY_BOOT = function() {
|
||||
var dir = '';
|
||||
if (isNodeJS) {
|
||||
require('../closure-library/closure/goog/bootstrap/nodejs')
|
||||
dir = 'blockly';
|
||||
} else {
|
||||
// Execute after Closure has loaded.
|
||||
if (!window.goog) {
|
||||
alert('Error: Closure not found. Read this:\\n' +
|
||||
'developers.google.com/blockly/hacking/closure');
|
||||
}
|
||||
dir = window.BLOCKLY_DIR.match(/[^\\/]+$/)[0];
|
||||
}
|
||||
""")
|
||||
f.write(add_dependency + "\n")
|
||||
f.write("\n")
|
||||
|
@ -139,17 +152,17 @@ delete this.BLOCKLY_DIR;
|
|||
delete this.BLOCKLY_BOOT;
|
||||
};
|
||||
|
||||
if (typeof DOMParser == 'undefined' && typeof require == 'function') {
|
||||
// Node.js needs DOMParser loaded separately.
|
||||
var DOMParser = require('xmldom').DOMParser;
|
||||
if (isNodeJS) {
|
||||
window.BLOCKLY_BOOT()
|
||||
module.exports = Blockly;
|
||||
} else {
|
||||
// Delete any existing Closure (e.g. Soy's nogoog_shim).
|
||||
document.write('<script>var goog = undefined;</script>');
|
||||
// Load fresh Closure Library.
|
||||
document.write('<script src="' + window.BLOCKLY_DIR +
|
||||
'/../closure-library/closure/goog/base.js"></script>');
|
||||
document.write('<script>window.BLOCKLY_BOOT()</script>');
|
||||
}
|
||||
|
||||
// Delete any existing Closure (e.g. Soy's nogoog_shim).
|
||||
document.write('<script>var goog = undefined;</script>');
|
||||
// Load fresh Closure Library.
|
||||
document.write('<script src="' + this.BLOCKLY_DIR +
|
||||
'/../closure-library/closure/goog/base.js"></script>');
|
||||
document.write('<script>this.BLOCKLY_BOOT()</script>');
|
||||
""")
|
||||
f.close()
|
||||
print("SUCCESS: " + target_filename)
|
||||
|
|
5
input.xml
Normal file
5
input.xml
Normal file
|
@ -0,0 +1,5 @@
|
|||
<xml xmlns="http://www.w3.org/1999/xhtml">
|
||||
<block type="colour_picker" id="11" x="93" y="12">
|
||||
<field name="COLOUR">#ff0000</field>
|
||||
</block>
|
||||
</xml>
|
16
readme.headless.md
Normal file
16
readme.headless.md
Normal file
|
@ -0,0 +1,16 @@
|
|||
# Blockly Headless
|
||||
|
||||
Running Blockly headless is valuable to allow for server side code generation.
|
||||
|
||||
The NodeJS program `app.headless.js` loads Blockly XML from `input.xml` and outputs python code on `stdout`.
|
||||
|
||||
### Prerequisites
|
||||
Be sure to have these installed on your system:
|
||||
- NodeJS -- http://nodejs.org/
|
||||
- NPM -- (Bundled with NodeJS)
|
||||
- closure-library -- http://developers.google.com/blockly/hacking/closure
|
||||
|
||||
## Getting Started
|
||||
1. run `npm install` in the blockly root directory(in the same location as the package.json).
|
||||
2. run `./build.py` to update the compressed files, as `build.py` **has changed**.
|
||||
3. run `node app.headless.js`
|
Loading…
Add table
Add a link
Reference in a new issue