From f0e2c72db513e0c239ce72c9be60d799a4cc991f Mon Sep 17 00:00:00 2001 From: Immortalin Date: Sat, 14 Nov 2015 19:24:58 +0800 Subject: [PATCH 1/9] Fix potential error due to naming --- build.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/build.py b/build.py index ccbc6deee..b79ab9943 100755 --- a/build.py +++ b/build.py @@ -445,8 +445,13 @@ if __name__ == "__main__": https://developers.google.com/blockly/hacking/closure""") sys.exit(1) - search_paths = calcdeps.ExpandDirectories( + try: + search_paths = calcdeps.ExpandDirectories( ["core", os.path.join(os.path.pardir, "closure-library")]) + except Exception as e: + search_paths = calcdeps.ExpandDirectories( + ["core", os.path.join(os.path.pardir, "google-closure-library")]) + # Run both tasks in parallel threads. # Uncompressed is limited by processor speed. From 8977ebf46f77998dc099b3c010c496157f4cc51c Mon Sep 17 00:00:00 2001 From: Blake Bourque Date: Mon, 5 Jan 2015 16:55:52 -0500 Subject: [PATCH 2/9] Changes needed to make headless work. --- .gitignore | 1 + app.headless.js | 29 +++++++++++++++++++ build.py | 71 +++++++++++++++++++++++++++------------------- input.xml | 5 ++++ readme.headless.md | 16 +++++++++++ 5 files changed, 93 insertions(+), 29 deletions(-) create mode 100644 app.headless.js create mode 100644 input.xml create mode 100644 readme.headless.md diff --git a/.gitignore b/.gitignore index 00504a0a9..709b48e44 100644 --- a/.gitignore +++ b/.gitignore @@ -5,3 +5,4 @@ npm-debug.log .project *.pyc *.komodoproject +node_modules \ No newline at end of file diff --git a/app.headless.js b/app.headless.js new file mode 100644 index 000000000..dfb0e22a2 --- /dev/null +++ b/app.headless.js @@ -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); +}); \ No newline at end of file diff --git a/build.py b/build.py index b79ab9943..9593d271b 100755 --- a/build.py +++ b/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(''); + // Load fresh Closure Library. + document.write(''); + document.write(''); } - -// Delete any existing Closure (e.g. Soy's nogoog_shim). -document.write(''); -// Load fresh Closure Library. -document.write(''); -document.write(''); """) f.close() print("SUCCESS: " + target_filename) diff --git a/input.xml b/input.xml new file mode 100644 index 000000000..d79b402ac --- /dev/null +++ b/input.xml @@ -0,0 +1,5 @@ + + + #ff0000 + + \ No newline at end of file diff --git a/readme.headless.md b/readme.headless.md new file mode 100644 index 000000000..66b7c4e92 --- /dev/null +++ b/readme.headless.md @@ -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` From 2cc62bff3d6bb27d58ba9588b2899e64b1660c65 Mon Sep 17 00:00:00 2001 From: Immortalin Date: Sat, 14 Nov 2015 21:56:05 +0800 Subject: [PATCH 3/9] cleaned up merge --- .gitignore | 1 - app.headless.js | 29 ----------------------------- input.xml | 5 ----- readme.headless.md | 16 ---------------- 4 files changed, 51 deletions(-) delete mode 100644 app.headless.js delete mode 100644 input.xml delete mode 100644 readme.headless.md diff --git a/.gitignore b/.gitignore index 709b48e44..00504a0a9 100644 --- a/.gitignore +++ b/.gitignore @@ -5,4 +5,3 @@ npm-debug.log .project *.pyc *.komodoproject -node_modules \ No newline at end of file diff --git a/app.headless.js b/app.headless.js deleted file mode 100644 index dfb0e22a2..000000000 --- a/app.headless.js +++ /dev/null @@ -1,29 +0,0 @@ -// 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); -}); \ No newline at end of file diff --git a/input.xml b/input.xml deleted file mode 100644 index d79b402ac..000000000 --- a/input.xml +++ /dev/null @@ -1,5 +0,0 @@ - - - #ff0000 - - \ No newline at end of file diff --git a/readme.headless.md b/readme.headless.md deleted file mode 100644 index 66b7c4e92..000000000 --- a/readme.headless.md +++ /dev/null @@ -1,16 +0,0 @@ -# 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` From 5efe2dd71f929985c16169075c792e29a6f0abdb Mon Sep 17 00:00:00 2001 From: Immortalin Date: Sat, 14 Nov 2015 22:23:40 +0800 Subject: [PATCH 4/9] fixed npm closure library issue --- build.py | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/build.py b/build.py index 9593d271b..671e20cbb 100755 --- a/build.py +++ b/build.py @@ -450,9 +450,11 @@ if __name__ == "__main__": "Please rename this directory.") elif os.path.isdir(os.path.join(os.path.pardir, "google-closure-library")): # When Closure is installed by npm, it is named "google-closure-library". - print("Error: Closure directory needs to be renamed from" - "'google-closure-library' to 'closure-library'.\n" - "Please rename this directory.") + calcdeps = import_path(os.path.join( + os.path.pardir, "closure-library", "closure", "bin", "calcdeps.py")) + # print("Error: Closure directory needs to be renamed from" + # "'google-closure-library' to 'closure-library'.\n" + # "Please rename this directory.") else: print("""Error: Closure not found. Read this: https://developers.google.com/blockly/hacking/closure""") From fae638c48be1f41531a7887572e3a0902bc8f143 Mon Sep 17 00:00:00 2001 From: Immortalin Date: Sat, 14 Nov 2015 22:35:09 +0800 Subject: [PATCH 5/9] Fix indentation --- build.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.py b/build.py index 671e20cbb..bfaca396f 100755 --- a/build.py +++ b/build.py @@ -450,7 +450,7 @@ if __name__ == "__main__": "Please rename this directory.") elif os.path.isdir(os.path.join(os.path.pardir, "google-closure-library")): # When Closure is installed by npm, it is named "google-closure-library". - calcdeps = import_path(os.path.join( + calcdeps = import_path(os.path.join( os.path.pardir, "closure-library", "closure", "bin", "calcdeps.py")) # print("Error: Closure directory needs to be renamed from" # "'google-closure-library' to 'closure-library'.\n" From 9a69dff34bad8cb6c010e8c787ae72d62a6b475e Mon Sep 17 00:00:00 2001 From: Immortalin Date: Sat, 14 Nov 2015 22:40:14 +0800 Subject: [PATCH 6/9] Fix typo --- build.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.py b/build.py index bfaca396f..8339a7109 100755 --- a/build.py +++ b/build.py @@ -451,7 +451,7 @@ if __name__ == "__main__": elif os.path.isdir(os.path.join(os.path.pardir, "google-closure-library")): # When Closure is installed by npm, it is named "google-closure-library". calcdeps = import_path(os.path.join( - os.path.pardir, "closure-library", "closure", "bin", "calcdeps.py")) + os.path.pardir, "google-closure-library", "closure", "bin", "calcdeps.py")) # print("Error: Closure directory needs to be renamed from" # "'google-closure-library' to 'closure-library'.\n" # "Please rename this directory.") From 7cc0b42c49fd441154908c57913052daa7bbd59f Mon Sep 17 00:00:00 2001 From: Immortalin Date: Sun, 15 Nov 2015 09:53:13 +0800 Subject: [PATCH 7/9] fixed code order --- build.py | 51 ++++++++++++++++++++++----------------------------- 1 file changed, 22 insertions(+), 29 deletions(-) diff --git a/build.py b/build.py index 8339a7109..914366314 100755 --- a/build.py +++ b/build.py @@ -75,32 +75,8 @@ class Gen_uncompressed(threading.Thread): self.search_paths = search_paths def run(self): - target_filename = "blockly_uncompressed.js" - add_dependency = [] - base_path = calcdeps.FindClosureBasePath(self.search_paths) - deps = calcdeps.BuildDependenciesFromFiles(self.search_paths) - filenames = calcdeps.CalculateDependencies(self.search_paths, - [os.path.join("core", "blockly.js")]) - - for dep in deps: - if dep.filename in filenames: - add_dependency.append(calcdeps.GetDepsLine(dep, base_path)) - add_dependency = "\n".join(add_dependency) - # Find the Blockly directory name and replace it with a JS variable. - # This allows blockly_uncompressed.js to be compiled on one computer and be - # used on another, even if the directory name differs. - m = re.search("[\\/]([^\\/]+)[\\/]core[\\/]blockly.js", add_dependency) - add_dependency = re.sub("([\\/])" + re.escape(m.group(1)) + - "([\\/]core[\\/])", '\\1" + dir + "\\2', add_dependency) - - provides = [] - for dep in deps: - if dep.filename in filenames: - if not dep.filename.startswith(os.pardir + os.sep): # "../" - provides.extend(dep.provides) - provides.sort() - - f = open(target_filename, "w") + target_filename = 'blockly_uncompressed.js' + f = open(target_filename, 'w') f.write(HEADER) f.write(""" var isNodeJS = !!(typeof module !== 'undefined' && module.exports); @@ -141,9 +117,26 @@ window.BLOCKLY_BOOT = function() { dir = window.BLOCKLY_DIR.match(/[^\\/]+$/)[0]; } """) - f.write(add_dependency + "\n") - f.write("\n") - f.write("// Load Blockly.\n") + add_dependency = [] + base_path = calcdeps.FindClosureBasePath(self.search_paths) + for dep in calcdeps.BuildDependenciesFromFiles(self.search_paths): + add_dependency.append(calcdeps.GetDepsLine(dep, base_path)) + add_dependency = '\n'.join(add_dependency) + # Find the Blockly directory name and replace it with a JS variable. + # This allows blockly_uncompressed.js to be compiled on one computer and be + # used on another, even if the directory name differs. + m = re.search('[\\/]([^\\/]+)[\\/]core[\\/]blockly.js', add_dependency) + add_dependency = re.sub('([\\/])' + re.escape(m.group(1)) + + '([\\/]core[\\/])', '\\1" + dir + "\\2', add_dependency) + f.write(add_dependency + '\n') + + provides = [] + for dep in calcdeps.BuildDependenciesFromFiles(self.search_paths): + if not dep.filename.startswith(os.pardir + os.sep): # '../' + provides.extend(dep.provides) + provides.sort() + f.write('\n') + f.write('// Load Blockly.\n') for provide in provides: f.write("goog.require('%s');\n" % provide) From 125ddf9d375a8e733b0b419256cb16a8bde1c87e Mon Sep 17 00:00:00 2001 From: Immortalin Date: Sun, 15 Nov 2015 13:19:32 +0800 Subject: [PATCH 8/9] Update name for better compatibility --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 6eba03ab2..cc24f2a90 100644 --- a/package.json +++ b/package.json @@ -1,5 +1,5 @@ { - "name": "blockly-src", + "name": "blockly", "version": "1.0.0", "description": "Blockly is a library for building visual programming editors.", "keywords": ["blockly"], From 00fa7e0b051df6dff5aa51f2dc8c234d3a72f6d5 Mon Sep 17 00:00:00 2001 From: Immortalin Date: Sun, 15 Nov 2015 13:22:43 +0800 Subject: [PATCH 9/9] Remove google-closure-library support. --- build.py | 17 ++++++----------- 1 file changed, 6 insertions(+), 11 deletions(-) diff --git a/build.py b/build.py index 914366314..2e2994790 100755 --- a/build.py +++ b/build.py @@ -443,23 +443,18 @@ if __name__ == "__main__": "Please rename this directory.") elif os.path.isdir(os.path.join(os.path.pardir, "google-closure-library")): # When Closure is installed by npm, it is named "google-closure-library". - calcdeps = import_path(os.path.join( - os.path.pardir, "google-closure-library", "closure", "bin", "calcdeps.py")) - # print("Error: Closure directory needs to be renamed from" - # "'google-closure-library' to 'closure-library'.\n" - # "Please rename this directory.") + #calcdeps = import_path(os.path.join( + # os.path.pardir, "google-closure-library", "closure", "bin", "calcdeps.py")) + print("Error: Closure directory needs to be renamed from" + "'google-closure-library' to 'closure-library'.\n" + "Please rename this directory.") else: print("""Error: Closure not found. Read this: https://developers.google.com/blockly/hacking/closure""") sys.exit(1) - try: - search_paths = calcdeps.ExpandDirectories( + search_paths = calcdeps.ExpandDirectories( ["core", os.path.join(os.path.pardir, "closure-library")]) - except Exception as e: - search_paths = calcdeps.ExpandDirectories( - ["core", os.path.join(os.path.pardir, "google-closure-library")]) - # Run both tasks in parallel threads. # Uncompressed is limited by processor speed.