2011-03-06 19:50:44 -05:00
|
|
|
/*
|
2013-01-28 21:03:27 -05:00
|
|
|
* Paper.js - The Swiss Army Knife of Vector Graphics Scripting.
|
2011-03-07 20:41:50 -05:00
|
|
|
* http://paperjs.org/
|
2011-06-30 06:01:51 -04:00
|
|
|
*
|
2013-01-28 21:03:27 -05:00
|
|
|
* Copyright (c) 2011 - 2013, Juerg Lehni & Jonathan Puckey
|
2011-03-06 19:50:44 -05:00
|
|
|
* http://lehni.org/ & http://jonathanpuckey.com/
|
2011-06-30 06:01:51 -04:00
|
|
|
*
|
2011-07-01 06:17:45 -04:00
|
|
|
* Distributed under the MIT license. See LICENSE file for details.
|
|
|
|
*
|
2011-03-07 20:41:50 -05:00
|
|
|
* All rights reserved.
|
2011-03-06 19:50:44 -05:00
|
|
|
*/
|
|
|
|
|
2011-07-24 19:25:23 -04:00
|
|
|
/**
|
|
|
|
* @name PaperScript
|
|
|
|
* @namespace
|
|
|
|
*/
|
2013-06-24 07:40:07 -04:00
|
|
|
// Note that due to the use of with(), PaperScript gets compiled outside the
|
|
|
|
// 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.
|
2013-07-19 18:48:50 -04:00
|
|
|
paper.PaperScope.prototype.PaperScript = (function(root) {
|
2013-06-28 09:39:00 -04:00
|
|
|
var Base = paper.Base,
|
|
|
|
PaperScope = paper.PaperScope,
|
2013-11-27 10:41:39 -05:00
|
|
|
// For local reference, for now only when setting lineNumberBase on
|
|
|
|
// Firefox.
|
|
|
|
PaperScript,
|
2013-07-18 12:49:30 -04:00
|
|
|
// Locally turn of exports and define for inlined acorn / esprima.
|
|
|
|
// Just declaring the local vars is enough, as they will be undefined.
|
|
|
|
exports, define,
|
|
|
|
// The scope into which the library is loaded.
|
|
|
|
scope = this;
|
2013-11-29 14:26:38 -05:00
|
|
|
/*#*/ if (__options.version == 'dev') {
|
2013-07-19 18:48:50 -04:00
|
|
|
// As the above inclusion loads code into the root scope during dev,
|
|
|
|
// set scope to root, so we can find the library.
|
|
|
|
scope = root;
|
2013-11-29 14:26:38 -05:00
|
|
|
/*#*/ } // __options.version == 'dev'
|
|
|
|
/*#*/ if (__options.parser == 'acorn') {
|
2013-10-10 18:20:30 -04:00
|
|
|
/*#*/ include('../../bower_components/acorn/acorn.min.js', { exports: false });
|
2013-11-29 14:26:38 -05:00
|
|
|
/*#*/ } else if (__options.parser == 'esprima') {
|
2013-10-10 18:20:30 -04:00
|
|
|
/*#*/ include('../../bower_components/esprima/esprima.min.js', { exports: false });
|
2013-06-27 07:46:20 -04:00
|
|
|
/*#*/ }
|
2011-03-03 17:55:18 -05:00
|
|
|
|
2012-11-18 13:06:16 -05:00
|
|
|
// Operators to overload
|
2011-03-03 17:19:12 -05:00
|
|
|
|
2012-11-18 13:06:16 -05:00
|
|
|
var binaryOperators = {
|
2013-06-28 08:15:49 -04:00
|
|
|
// The hidden math functions are to be injected specifically, see below.
|
|
|
|
'+': '_add',
|
|
|
|
'-': '_subtract',
|
|
|
|
'*': '_multiply',
|
|
|
|
'/': '_divide',
|
|
|
|
'%': '_modulo',
|
|
|
|
// Use the real equals.
|
2011-03-03 17:19:12 -05:00
|
|
|
'==': 'equals',
|
|
|
|
'!=': 'equals'
|
|
|
|
};
|
|
|
|
|
2012-11-18 13:06:16 -05:00
|
|
|
var unaryOperators = {
|
2013-06-28 08:15:49 -04:00
|
|
|
'-': '_negate',
|
2012-11-18 13:06:16 -05:00
|
|
|
'+': null
|
|
|
|
};
|
|
|
|
|
2013-11-14 08:42:28 -05:00
|
|
|
// Inject underscored math functions as aliases to Point, Size and Color.
|
2013-06-28 08:15:49 -04:00
|
|
|
var fields = Base.each(
|
2013-11-14 08:42:28 -05:00
|
|
|
['add', 'subtract', 'multiply', 'divide', 'modulo', 'negate'],
|
2013-06-28 08:15:49 -04:00
|
|
|
function(name) {
|
|
|
|
this['_' + name] = '#' + name;
|
|
|
|
},
|
|
|
|
{}
|
|
|
|
);
|
|
|
|
paper.Point.inject(fields);
|
|
|
|
paper.Size.inject(fields);
|
|
|
|
paper.Color.inject(fields);
|
|
|
|
|
2012-11-18 13:06:16 -05:00
|
|
|
// Use very short name for the binary operator (_$_) as well as the
|
|
|
|
// unary operator ($_), as operations will be replaced with then.
|
|
|
|
// The underscores stands for the values, and the $ for the operators.
|
|
|
|
|
|
|
|
// Binary Operator Handler
|
|
|
|
function _$_(left, operator, right) {
|
|
|
|
var handler = binaryOperators[operator];
|
2011-03-03 17:19:12 -05:00
|
|
|
if (left && left[handler]) {
|
|
|
|
var res = left[handler](right);
|
2012-11-02 18:58:41 -04:00
|
|
|
return operator === '!=' ? !res : res;
|
2011-03-03 17:19:12 -05:00
|
|
|
}
|
|
|
|
switch (operator) {
|
|
|
|
case '+': return left + right;
|
|
|
|
case '-': return left - right;
|
|
|
|
case '*': return left * right;
|
|
|
|
case '/': return left / right;
|
|
|
|
case '%': return left % right;
|
|
|
|
case '==': return left == right;
|
|
|
|
case '!=': return left != right;
|
|
|
|
}
|
2012-11-02 18:58:41 -04:00
|
|
|
}
|
2011-03-03 17:19:12 -05:00
|
|
|
|
2012-11-18 13:06:16 -05:00
|
|
|
// Unary Operator Handler
|
|
|
|
function $_(operator, value) {
|
|
|
|
var handler = unaryOperators[operator];
|
|
|
|
if (handler && value && value[handler])
|
2011-03-03 20:22:08 -05:00
|
|
|
return value[handler]();
|
2011-03-03 17:19:12 -05:00
|
|
|
switch (operator) {
|
2011-03-03 20:22:08 -05:00
|
|
|
case '+': return +value;
|
|
|
|
case '-': return -value;
|
2011-03-03 17:19:12 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// AST Helpers
|
|
|
|
|
2011-07-24 19:25:23 -04:00
|
|
|
/**
|
|
|
|
* Compiles PaperScript code into JavaScript code.
|
|
|
|
*
|
|
|
|
* @name PaperScript.compile
|
|
|
|
* @function
|
2013-08-23 22:45:28 -04:00
|
|
|
* @param {String} code The PaperScript code
|
|
|
|
* @return {String} the compiled PaperScript as JavaScript code
|
2011-07-24 19:25:23 -04:00
|
|
|
*/
|
2011-03-03 13:31:56 -05:00
|
|
|
function compile(code) {
|
2012-11-18 13:06:16 -05:00
|
|
|
// Use Acorn or Esprima to translate the code into an AST structure
|
|
|
|
// which is then walked and parsed for operators to overload.
|
|
|
|
// Instead of modifying the AST and converting back to code, we directly
|
|
|
|
// change the source code based on the parser's range information, so we
|
|
|
|
// can preserve line-numbers in syntax errors and remove the need for
|
|
|
|
// Escodegen.
|
|
|
|
|
|
|
|
// Tracks code insertions so we can add their differences to the
|
|
|
|
// original offsets.
|
|
|
|
var insertions = [];
|
|
|
|
|
|
|
|
// Converts an original offset to the one in the current state of the
|
|
|
|
// modified code.
|
|
|
|
function getOffset(offset) {
|
|
|
|
// Add all insertions before this location together to calculate
|
|
|
|
// the current offset
|
|
|
|
for (var i = 0, l = insertions.length; i < l; i++) {
|
|
|
|
var insertion = insertions[i];
|
|
|
|
if (insertion[0] >= offset)
|
|
|
|
break;
|
|
|
|
offset += insertion[1];
|
|
|
|
}
|
|
|
|
return offset;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Returns the node's code as a string, taking insertions into account.
|
|
|
|
function getCode(node) {
|
|
|
|
return code.substring(getOffset(node.range[0]),
|
|
|
|
getOffset(node.range[1]));
|
|
|
|
}
|
|
|
|
|
|
|
|
// Replaces the node's code with a new version and keeps insertions
|
|
|
|
// information up-to-date.
|
|
|
|
function replaceCode(node, str) {
|
|
|
|
var start = getOffset(node.range[0]),
|
|
|
|
end = getOffset(node.range[1]);
|
|
|
|
var insert = 0;
|
|
|
|
// Sort insertions by their offset, so getOffest() can do its thing
|
|
|
|
for (var i = insertions.length - 1; i >= 0; i--) {
|
|
|
|
if (start > insertions[i][0]) {
|
|
|
|
insert = i + 1;
|
|
|
|
break;
|
2011-03-03 17:19:12 -05:00
|
|
|
}
|
|
|
|
}
|
2012-11-18 13:06:16 -05:00
|
|
|
insertions.splice(insert, 0, [start, str.length - end + start]);
|
|
|
|
code = code.substring(0, start) + str + code.substring(end);
|
|
|
|
}
|
2011-03-03 17:19:12 -05:00
|
|
|
|
2012-11-18 13:06:16 -05:00
|
|
|
// Recursively walks the AST and replaces the code of certain nodes
|
2013-11-25 13:34:39 -05:00
|
|
|
function walkAST(node, parent) {
|
2013-08-09 13:58:04 -04:00
|
|
|
if (!node)
|
2013-06-18 21:18:39 -04:00
|
|
|
return;
|
2012-11-18 13:06:16 -05:00
|
|
|
for (var key in node) {
|
|
|
|
if (key === 'range')
|
|
|
|
continue;
|
|
|
|
var value = node[key];
|
|
|
|
if (Array.isArray(value)) {
|
|
|
|
for (var i = 0, l = value.length; i < l; i++)
|
2013-11-25 13:34:39 -05:00
|
|
|
walkAST(value[i], node);
|
2013-02-24 18:41:06 -05:00
|
|
|
} else if (value && typeof value === 'object') {
|
|
|
|
// We cannot use Base.isPlainObject() for these since
|
|
|
|
// Acorn.js uses its own internal prototypes now.
|
2013-11-25 13:34:39 -05:00
|
|
|
walkAST(value, node);
|
2012-11-18 13:06:16 -05:00
|
|
|
}
|
|
|
|
}
|
2012-11-21 15:17:01 -05:00
|
|
|
switch (node && node.type) {
|
2012-11-18 13:06:16 -05:00
|
|
|
case 'BinaryExpression':
|
|
|
|
if (node.operator in binaryOperators
|
|
|
|
&& node.left.type !== 'Literal') {
|
|
|
|
var left = getCode(node.left),
|
|
|
|
right = getCode(node.right);
|
|
|
|
replaceCode(node, '_$_(' + left + ', "' + node.operator
|
|
|
|
+ '", ' + right + ')');
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case 'AssignmentExpression':
|
|
|
|
if (/^.=$/.test(node.operator)
|
|
|
|
&& node.left.type !== 'Literal') {
|
|
|
|
var left = getCode(node.left),
|
|
|
|
right = getCode(node.right);
|
|
|
|
replaceCode(node, left + ' = _$_(' + left + ', "'
|
|
|
|
+ node.operator[0] + '", ' + right + ')');
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case 'UpdateExpression':
|
2013-08-09 13:58:04 -04:00
|
|
|
if (!node.prefix && !(parent && (
|
|
|
|
// We need to filter out parents that are comparison
|
|
|
|
// operators, e.g. for situations like if (++i < 1),
|
|
|
|
// as we can't replace that with if (_$_(i, "+", 1) < 1)
|
|
|
|
// Match any operator beginning with =, !, < and >.
|
|
|
|
parent.type === 'BinaryExpression'
|
|
|
|
&& /^[=!<>]/.test(parent.operator)
|
|
|
|
// array[i++] is a MemberExpression with computed = true
|
|
|
|
// We can't replace that with array[_$_(i, "+", 1)].
|
|
|
|
|| parent.type === 'MemberExpression'
|
|
|
|
&& parent.computed))) {
|
2012-11-18 13:06:16 -05:00
|
|
|
var arg = getCode(node.argument);
|
|
|
|
replaceCode(node, arg + ' = _$_(' + arg + ', "'
|
|
|
|
+ node.operator[0] + '", 1)');
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case 'UnaryExpression':
|
|
|
|
if (node.operator in unaryOperators
|
|
|
|
&& node.argument.type !== 'Literal') {
|
|
|
|
var arg = getCode(node.argument);
|
|
|
|
replaceCode(node, '$_("' + node.operator + '", '
|
|
|
|
+ arg + ')');
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// Now do the parsing magic
|
2013-11-29 14:26:38 -05:00
|
|
|
/*#*/ if (__options.parser == 'acorn') {
|
2013-11-25 13:34:39 -05:00
|
|
|
walkAST(scope.acorn.parse(code, { ranges: true }));
|
2013-11-29 14:26:38 -05:00
|
|
|
/*#*/ } else if (__options.parser == 'esprima') {
|
2013-11-25 13:34:39 -05:00
|
|
|
walkAST(scope.esprima.parse(code, { range: true }));
|
2012-11-18 13:06:16 -05:00
|
|
|
/*#*/ }
|
|
|
|
return code;
|
2011-03-03 13:31:56 -05:00
|
|
|
}
|
|
|
|
|
2011-07-24 19:25:23 -04:00
|
|
|
/**
|
2011-07-27 17:39:58 -04:00
|
|
|
* Evaluates parsed PaperScript code in the passed {@link PaperScope}
|
2011-08-01 03:52:51 -04:00
|
|
|
* object. It also installs handlers automatically for us.
|
2011-07-24 19:25:23 -04:00
|
|
|
*
|
|
|
|
* @name PaperScript.evaluate
|
|
|
|
* @function
|
2013-08-23 22:45:28 -04:00
|
|
|
* @param {String} code The PaperScript code
|
|
|
|
* @param {PaperScript} scope The scope in which the code is executed
|
|
|
|
* @return {Object} the result of the code evaluation
|
2011-07-24 19:25:23 -04:00
|
|
|
*/
|
2011-05-15 20:22:06 -04:00
|
|
|
function evaluate(code, scope) {
|
2011-07-19 18:53:13 -04:00
|
|
|
// Set currently active scope.
|
|
|
|
paper = scope;
|
2012-09-01 13:27:38 -04:00
|
|
|
var view = scope.project && scope.project.view,
|
2011-05-16 06:00:33 -04:00
|
|
|
res;
|
2011-06-30 06:01:51 -04:00
|
|
|
// Define variables for potential handlers, so eval() calls below to
|
2011-05-16 06:00:33 -04:00
|
|
|
// fetch their values do not require try-catch around them.
|
|
|
|
// Use with(){} in order to make the scope the current 'global' scope
|
|
|
|
// instead of window.
|
|
|
|
with (scope) {
|
|
|
|
// Within this, use a function scope, so local variables to not try
|
2011-05-16 06:19:47 -04:00
|
|
|
// and set themselves on the scope object.
|
2011-05-16 06:00:33 -04:00
|
|
|
(function() {
|
2012-11-07 04:02:09 -05:00
|
|
|
var onActivate, onDeactivate, onEditOptions,
|
2011-12-27 10:05:02 -05:00
|
|
|
onMouseDown, onMouseUp, onMouseDrag, onMouseMove,
|
|
|
|
onKeyDown, onKeyUp, onFrame, onResize;
|
2013-11-27 10:41:39 -05:00
|
|
|
code = compile(code);
|
2013-11-29 14:26:38 -05:00
|
|
|
/*#*/ if (__options.environment == 'browser') {
|
2013-11-27 10:41:39 -05:00
|
|
|
if (root.InstallTrigger) { // Firefox
|
|
|
|
// On Firefox, all error numbers inside evaled code are
|
|
|
|
// relative to the line where the eval happened. Totally
|
2013-11-27 13:07:02 -05:00
|
|
|
// silly, but that's how it is. So we're calculating the
|
|
|
|
// base of lineNumbers, to remove it again from reported
|
|
|
|
// errors. Luckily, Firefox is the only browser where we can
|
|
|
|
// define the lineNumber for exceptions.
|
|
|
|
var handle = PaperScript.handleException;
|
|
|
|
if (!handle) {
|
|
|
|
handle = PaperScript.handleException = function(e) {
|
|
|
|
throw e.lineNumber >= lineNumber
|
|
|
|
? new Error(e.message, e.fileName,
|
|
|
|
e.lineNumber - lineNumber)
|
|
|
|
: e;
|
|
|
|
}
|
|
|
|
// We're using a crazy hack to detect wether the library
|
|
|
|
// is minified or not: By generating a second error on
|
|
|
|
// the 2nd line and using the difference in line numbers
|
|
|
|
// to calculate the offset to the eval, it works in both
|
|
|
|
// casees.
|
|
|
|
var lineNumber = new Error().lineNumber;
|
|
|
|
lineNumber += (new Error().lineNumber - lineNumber) * 3;
|
|
|
|
}
|
|
|
|
try {
|
|
|
|
// Add a semi-colon at the start so Firefox doesn't
|
|
|
|
// swallow empty lines and shift error messages.
|
|
|
|
res = eval(';' + code);
|
|
|
|
} catch (e) {
|
|
|
|
handle(e);
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
res = eval(code);
|
2013-11-27 10:41:39 -05:00
|
|
|
}
|
2013-11-29 14:26:38 -05:00
|
|
|
/*#*/ } else { // !__options.environment == 'browser'
|
2013-11-27 10:41:39 -05:00
|
|
|
res = eval(code);
|
2013-11-29 14:26:38 -05:00
|
|
|
/*#*/ } // !__options.environment == 'browser'
|
2011-12-27 10:33:17 -05:00
|
|
|
// Only look for tool handlers if something resembling their
|
|
|
|
// name is contained in the code.
|
|
|
|
if (/on(?:Key|Mouse)(?:Up|Down|Move|Drag)/.test(code)) {
|
2013-06-24 07:40:07 -04:00
|
|
|
Base.each(paper.Tool.prototype._events, function(key) {
|
2011-12-27 10:33:17 -05:00
|
|
|
var value = eval(key);
|
|
|
|
if (value) {
|
|
|
|
// Use the getTool accessor that handles auto tool
|
|
|
|
// creation for us:
|
|
|
|
scope.getTool()[key] = value;
|
|
|
|
}
|
2011-05-16 06:00:33 -04:00
|
|
|
});
|
|
|
|
}
|
|
|
|
if (view) {
|
2011-11-11 12:29:28 -05:00
|
|
|
view.setOnResize(onResize);
|
2011-11-12 10:31:22 -05:00
|
|
|
// Fire resize event directly, so any user
|
|
|
|
// defined resize handlers are called.
|
|
|
|
view.fire('resize', {
|
|
|
|
size: view.size,
|
|
|
|
delta: new Point()
|
|
|
|
});
|
2013-11-29 14:03:52 -05:00
|
|
|
if (onFrame)
|
|
|
|
view.setOnFrame(onFrame);
|
2011-08-01 06:02:00 -04:00
|
|
|
// Automatically draw view at the end.
|
|
|
|
view.draw();
|
2011-05-15 18:37:40 -04:00
|
|
|
}
|
2011-05-16 06:00:33 -04:00
|
|
|
}).call(scope);
|
2011-03-03 13:31:56 -05:00
|
|
|
}
|
2011-05-16 06:00:33 -04:00
|
|
|
return res;
|
2011-03-03 13:31:56 -05:00
|
|
|
}
|
|
|
|
|
2013-11-29 14:26:38 -05:00
|
|
|
/*#*/ if (__options.environment == 'browser') {
|
2011-03-07 19:17:19 -05:00
|
|
|
|
|
|
|
function load() {
|
2013-11-26 17:46:53 -05:00
|
|
|
Base.each(document.getElementsByTagName('script'), function(script) {
|
2011-05-15 06:32:42 -04:00
|
|
|
// Only load this script if it not loaded already.
|
2011-07-09 10:58:53 -04:00
|
|
|
// Support both text/paperscript and text/x-paperscript:
|
2011-07-09 11:11:57 -04:00
|
|
|
if (/^text\/(?:x-|)paperscript$/.test(script.type)
|
2012-10-23 23:05:01 -04:00
|
|
|
&& !script.getAttribute('data-paper-ignore')) {
|
2011-05-14 07:15:31 -04:00
|
|
|
// Produce a new PaperScope for this script now. Scopes are
|
|
|
|
// cheap so let's not worry about the initial one that was
|
|
|
|
// already created.
|
2011-07-27 17:39:58 -04:00
|
|
|
// Define an id for each PaperScript, so its scope can be
|
2011-05-15 19:29:29 -04:00
|
|
|
// retrieved through PaperScope.get().
|
2011-07-27 17:39:58 -04:00
|
|
|
// If a canvas id is provided, pass it on to the PaperScope
|
|
|
|
// so a project is created for it now.
|
2013-06-24 07:23:34 -04:00
|
|
|
var canvas = PaperScope.getAttribute(script, 'canvas'),
|
2013-02-15 03:15:44 -05:00
|
|
|
// See if there already is a scope for this canvas and reuse
|
|
|
|
// it, to support multiple scripts per canvas. Otherwise
|
|
|
|
// create a new one.
|
|
|
|
scope = PaperScope.get(canvas)
|
2013-11-02 16:17:11 -04:00
|
|
|
|| new PaperScope(script).setup(canvas),
|
|
|
|
src = script.src;
|
|
|
|
if (src) {
|
|
|
|
// If we're loading from a source, request that first and
|
|
|
|
// then run later.
|
2013-11-26 17:46:53 -05:00
|
|
|
paper.Http.request('get', src, function(code) {
|
2013-11-02 16:17:11 -04:00
|
|
|
evaluate(code, scope);
|
2013-11-26 17:46:53 -05:00
|
|
|
});
|
2011-07-27 17:39:58 -04:00
|
|
|
} else {
|
|
|
|
// We can simply get the code form the script tag.
|
|
|
|
evaluate(script.innerHTML, scope);
|
|
|
|
}
|
2011-05-07 15:50:12 -04:00
|
|
|
// Mark script as loaded now.
|
2012-10-23 23:05:01 -04:00
|
|
|
script.setAttribute('data-paper-ignore', true);
|
2011-03-03 13:31:56 -05:00
|
|
|
}
|
2013-11-29 13:53:48 -05:00
|
|
|
}, this);
|
2011-03-07 13:35:48 -05:00
|
|
|
}
|
2011-03-03 13:31:56 -05:00
|
|
|
|
2013-02-14 15:50:51 -05:00
|
|
|
// Catch cases where paper.js is loaded after the browser event has already
|
|
|
|
// occurred.
|
|
|
|
if (document.readyState === 'complete') {
|
2013-01-01 18:57:30 -05:00
|
|
|
// Handle it asynchronously
|
2013-02-14 15:50:51 -05:00
|
|
|
setTimeout(load);
|
2013-01-01 18:57:30 -05:00
|
|
|
} else {
|
2013-06-24 07:40:07 -04:00
|
|
|
paper.DomEvent.add(window, { load: load });
|
2013-01-01 18:57:30 -05:00
|
|
|
}
|
2011-03-07 13:35:48 -05:00
|
|
|
|
2013-11-27 10:41:39 -05:00
|
|
|
return PaperScript = {
|
2011-03-07 13:35:48 -05:00
|
|
|
compile: compile,
|
2011-05-15 20:22:06 -04:00
|
|
|
evaluate: evaluate,
|
2013-11-27 10:41:39 -05:00
|
|
|
load: load,
|
|
|
|
lineNumberBase: 0
|
2011-03-07 13:35:48 -05:00
|
|
|
};
|
|
|
|
|
2013-11-29 14:26:38 -05:00
|
|
|
/*#*/ } else { // !__options.environment == 'browser'
|
|
|
|
/*#*/ if (__options.environment == 'node') {
|
2013-06-27 16:52:30 -04:00
|
|
|
|
|
|
|
// Register the .pjs extension for automatic compilation as PaperScript
|
|
|
|
var fs = require('fs'),
|
|
|
|
path = require('path');
|
|
|
|
|
|
|
|
require.extensions['.pjs'] = function(module, uri) {
|
|
|
|
var source = 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;
|
|
|
|
evaluate(source, scope);
|
|
|
|
module.exports = scope;
|
|
|
|
};
|
|
|
|
|
2013-11-29 14:26:38 -05:00
|
|
|
/*#*/ } // __options.environment == 'node'
|
2011-03-03 13:31:56 -05:00
|
|
|
|
2013-11-27 10:41:39 -05:00
|
|
|
return PaperScript = {
|
2011-03-03 13:31:56 -05:00
|
|
|
compile: compile,
|
2011-05-15 20:22:06 -04:00
|
|
|
evaluate: evaluate
|
2011-03-03 13:31:56 -05:00
|
|
|
};
|
2011-03-07 13:35:48 -05:00
|
|
|
|
2013-11-29 14:26:38 -05:00
|
|
|
/*#*/ } // !__options.environment == 'browser'
|
2013-07-19 18:48:50 -04:00
|
|
|
})(this);
|