From 4f5dac85677e32dbd40b3d184e103c4ae1536b22 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=BCrg=20Lehni?= Date: Thu, 27 Jun 2013 13:49:04 -0700 Subject: [PATCH] Improved PrePro to be able to dynamically load Node.js code too, and improve load.js to handle both environments. Also moved PaperScript .pjs extension code to PaperScript, and DOM related Node.js code to dom/node.js --- examples/Node.js/Raster.js | 1 - package.json | 4 +- src/core/PaperScript.js | 23 +++++++- src/dom/node.js | 59 +++++++++++++++++++ src/export.js | 18 ++++++ src/load.js | 50 +++++++++++----- src/node/index.js | 118 ------------------------------------- src/options.js | 5 +- src/paper.js | 6 ++ src/ui/CanvasView.js | 3 + 10 files changed, 148 insertions(+), 139 deletions(-) create mode 100644 src/dom/node.js delete mode 100644 src/node/index.js diff --git a/examples/Node.js/Raster.js b/examples/Node.js/Raster.js index 14ac0fb0..9d70aa22 100644 --- a/examples/Node.js/Raster.js +++ b/examples/Node.js/Raster.js @@ -6,7 +6,6 @@ var data = "data:image/jpeg;base64,/9j/4QAYRXhpZgAASUkqAAgAAAAAAAAAAAAAAP/sABFEd paper.setup(new paper.Canvas(600, 600)); with (paper) { - console.log(Raster); var raster = new paper.Raster(data); raster.position = view.center; paper.view.exportFrames({ diff --git a/package.json b/package.json index cb6cf4f5..4cf346fd 100644 --- a/package.json +++ b/package.json @@ -6,7 +6,7 @@ "Jürg Lehni (http://lehni.org)", "Jonathan Puckey (http://studiomoniker.com)" ], - "main": "./src/node/index.js", + "main": "./src/load.js", "engines": { "node": ">= 0.4.0" }, @@ -29,7 +29,7 @@ ], "devDependencies": { "uglify-js": "~2.3.6", - "prepro": "~0.6.0", + "prepro": "~0.7.0", "grunt": "~0.4.1", "grunt-contrib-uglify": "~0.2.2" } diff --git a/src/core/PaperScript.js b/src/core/PaperScript.js index 5d348a17..ce809918 100644 --- a/src/core/PaperScript.js +++ b/src/core/PaperScript.js @@ -18,7 +18,7 @@ // main paper scope, and is added to the PaperScope class. This allows for // better minification and the future use of strict mode once it makes sense // in terms of performance. -paper.PaperScope.prototype.PaperScript = new function() { +var PaperScript = paper.PaperScope.prototype.PaperScript = new function() { /*#*/ if (options.parser == 'acorn') { /*#*/ include('../../components/acorn/acorn.min.js'); /*#*/ } else if (options.parser == 'esprima') { @@ -332,3 +332,24 @@ paper.PaperScope.prototype.PaperScript = new function() { /*#*/ } // !options.browser }; + +/*#*/ if (options.node) { + +// Register the .pjs extension and have it automatically compile as PaperScript + +var fs = require('fs'), + path = require('path'); + +require.extensions['.pjs'] = function(module, uri) { + var source = PaperScript.compile(fs.readFileSync(uri, 'utf8')), + scope = new PaperScope(); + scope.__filename = uri; + scope.__dirname = path.dirname(uri); + // Expose core methods and values + scope.require = require; + scope.console = console; + PaperScript.evaluate(source, scope); + module.exports = scope; +}; + +/*#*/ } // options.node diff --git a/src/dom/node.js b/src/dom/node.js new file mode 100644 index 00000000..ad9ff093 --- /dev/null +++ b/src/dom/node.js @@ -0,0 +1,59 @@ +/* + * Paper.js - The Swiss Army Knife of Vector Graphics Scripting. + * http://paperjs.org/ + * + * Copyright (c) 2011 - 2013, Juerg Lehni & Jonathan Puckey + * http://lehni.org/ & http://jonathanpuckey.com/ + * + * Distributed under the MIT license. See LICENSE file for details. + * + * All rights reserved. + */ + +// Node.js emulation layer of browser based environment, based on node-canvas +// and jsdom. + +// console.log(__dirname); + +var jsdom = require('jsdom'), + domToHtml = require('jsdom/lib/jsdom/browser/domtohtml').domToHtml, + // Node Canvas library: https://github.com/learnboost/node-canvas + Canvas = require('canvas'); + +// Expose global browser variables and create a document and a window using +// jsdom, e.g. for import/exportSVG() +var document = jsdom.jsdom(''), + window = document.createWindow(), + navigator = window.navigator, + HTMLCanvasElement = Canvas, + Image = Canvas.Image; + +// Define XMLSerializer and DOMParser shims, to emulate browser behavior. +// TODO: Put this into a simple node module, with dependency on jsdom? +function XMLSerializer() { +} + +XMLSerializer.prototype.serializeToString = function(node) { + var text = domToHtml(node); + // Fix a jsdom issue where all SVG tagNames are lowercased: + // https://github.com/tmpvar/jsdom/issues/620 + var tagNames = ['linearGradient', 'radialGradient', 'clipPath']; + for (var i = 0, l = tagNames.length; i < l; i++) { + var tagName = tagNames[i]; + text = text.replace( + new RegExp('(<|'); - // Now that we have include(), load this file again, which will execute the - // lower part of the code the 2nd time around. - document.write(''); +if (typeof window !== 'undefined') { + // Browser based loading through PrePro: + if (!window.include) { + var scripts = document.getElementsByTagName('script'); + var src = scripts[scripts.length - 1].getAttribute('src'); + // Assume that we're loading browser.js from a root folder, either + // through dist/paper.js, or directly through src/load.js, and match + // root as all the parts of the path that lead to that folder. + var root = src.match(/^(.*\/)\w*\//)[1]; + // First load the PrePro's browser.js file, which provides the include() + // function for the browser. + document.write(''); + // Now that we have include(), load this file again, which will execute + // the lower part of the code the 2nd time around. + document.write(''); + } else { + include('options.js'); + include('paper.js'); + } } else { - include('options.js'); - include('paper.js'); + // Node based loading through PrePro: + var prepro = require('prepro/lib/node.js'); + // Include deafult browser options. + prepro.include('options.js'); + // Override node specific options. + prepro.setOptions({ + browser: false, + node: true, + stats: false + }); + // Load Paper.js library files. + prepro.include('paper.js'); + // Export the paper scope. + module.exports = prepro.context.paper; } diff --git a/src/node/index.js b/src/node/index.js deleted file mode 100644 index 715616be..00000000 --- a/src/node/index.js +++ /dev/null @@ -1,118 +0,0 @@ -/* - * Paper.js - The Swiss Army Knife of Vector Graphics Scripting. - * http://paperjs.org/ - * - * Copyright (c) 2011 - 2013, Juerg Lehni & Jonathan Puckey - * http://lehni.org/ & http://jonathanpuckey.com/ - * - * Distributed under the MIT license. See LICENSE file for details. - * - * All rights reserved. - */ - -var fs = require('fs'), - vm = require('vm'), - path = require('path'), - // Node Canvas library: https://github.com/learnboost/node-canvas - Canvas = require('canvas'), - jsdom = require('jsdom'), - domToHtml = require('jsdom/lib/jsdom/browser/domtohtml').domToHtml; - -// Load the options from load.js, but evaluate into local scope: -eval(fs.readFileSync(path.resolve(__dirname, '../options.js'), 'utf8')); -// Change node.js specific settings. Use 'dev' version for on-the fly -// compilation of separate files, and set to correct value after. -options.version = 'dev'; -options.browser = false; -options.node = true; -options.stats = false; - -// Create a document and a window using jsdom, e.g. for exportSVG() -var doc = jsdom.jsdom(''), - win = doc.createWindow(); - -// Define XMLSerializer and DOMParser shims, to emulate browser behavior. -// TODO: Put this into a simple node module, with dependency on jsdom? -function XMLSerializer() { -} - -XMLSerializer.prototype.serializeToString = function(node) { - var text = domToHtml(node); - // Fix a jsdom issue where all SVG tagNames are lowercased: - // https://github.com/tmpvar/jsdom/issues/620 - var tagNames = ['linearGradient', 'radialGradient', 'clipPath']; - for (var i = 0, l = tagNames.length; i < l; i++) { - var tagName = tagNames[i]; - text = text.replace( - new RegExp('(<|