mirror of
https://github.com/scratchfoundation/paper.js.git
synced 2025-01-03 19:45:44 -05:00
parent
c479ec9272
commit
46f415ca81
2 changed files with 74 additions and 49 deletions
|
@ -95,8 +95,6 @@ Base.exports.PaperScript = (function() {
|
|||
return scope.acorn.parse(code, options);
|
||||
}
|
||||
|
||||
var sourceMaps = {};
|
||||
|
||||
/**
|
||||
* Compiles PaperScript code into JavaScript code.
|
||||
*
|
||||
|
@ -104,13 +102,14 @@ Base.exports.PaperScript = (function() {
|
|||
* @function
|
||||
*
|
||||
* @option options.url {String} the url of the source, for source-map
|
||||
* debugging
|
||||
* generation
|
||||
* @option options.source {String} the source to be used for the source-
|
||||
* mapping, in case the code that's passed in has already been mingled.
|
||||
*
|
||||
* @param {String} code the PaperScript code
|
||||
* @param {Object} [option] the compilation options
|
||||
* @return {String} the compiled PaperScript translated into JavaScript code
|
||||
* @return {Object} an object holding the compiled PaperScript translated
|
||||
* into JavaScript code along with source-maps and other information.
|
||||
*/
|
||||
function compile(code, options) {
|
||||
if (!code)
|
||||
|
@ -285,21 +284,23 @@ Base.exports.PaperScript = (function() {
|
|||
agent = paper.agent,
|
||||
version = agent.versionNumber,
|
||||
offsetCode = false,
|
||||
sourceMap = null,
|
||||
sourceMaps = options.sourceMaps,
|
||||
// Include the original code in the sourceMap if there is no linked
|
||||
// source file so the debugger can still display it correctly.
|
||||
source = options.source || code,
|
||||
lineBreaks = /\r\n|\n|\r/mg,
|
||||
offset = 0;
|
||||
offset = options.offset || 0,
|
||||
map;
|
||||
// TODO: Verify these browser versions for source map support, and check
|
||||
// other browsers.
|
||||
if (agent.chrome && version >= 30
|
||||
if (sourceMaps && (agent.chrome && version >= 30
|
||||
|| agent.webkit && version >= 537.76 // >= Safari 7.0.4
|
||||
|| agent.firefox && version >= 23
|
||||
|| agent.node) {
|
||||
|| agent.node)) {
|
||||
if (agent.node) {
|
||||
code = 'require("source-map-support").install(paper.PaperScript.sourceMapSupport);\n' + code;
|
||||
offset = -3; // -2 for function body, - 1 for require("source-map-support")
|
||||
// -2 required to remove function header:
|
||||
// https://code.google.com/p/chromium/issues/detail?id=331655
|
||||
offset -= 2;
|
||||
} else if (url && window.location.href.indexOf(url) === 0) {
|
||||
// If the code stems from the actual html page, determine the
|
||||
// offset of inlined code.
|
||||
|
@ -309,18 +310,21 @@ Base.exports.PaperScript = (function() {
|
|||
offset = html.substr(0, html.indexOf(code) + 1).match(
|
||||
lineBreaks).length + 1;
|
||||
}
|
||||
// A hack required by most versions of browsers except chrome 36+:
|
||||
// Instead of starting the mappings at the given offset, we have to
|
||||
// shift the actual code down to the place in the original file, as
|
||||
// source-map support seems incomplete in these browsers.
|
||||
// TODO: Report as bugs?
|
||||
offsetCode = offset > 0 && (!browser.chrome || version < 36);
|
||||
// A hack required by older versions of browsers to align inlined
|
||||
// code: Instead of starting the mappings at the given offset, we
|
||||
// have to shift the actual code down to the place in the original
|
||||
// file, as source-map support seems incomplete in these browsers.
|
||||
offsetCode = offset > 0 && !(
|
||||
agent.chrome && version >= 36 ||
|
||||
agent.safari && version >= 600 ||
|
||||
agent.firefox && version >= 40 ||
|
||||
agent.node);
|
||||
var mappings = ['AA' + encodeVLQ(offsetCode ? 0 : offset) + 'A'];
|
||||
// Create empty entries by the amount of lines + 1, so join can be
|
||||
// used below to produce the actual instructions that many times.
|
||||
mappings.length = (code.match(lineBreaks) || []).length + 1
|
||||
+ (offsetCode ? offset : 0);
|
||||
sourceMap = {
|
||||
map = {
|
||||
version: 3,
|
||||
file: url,
|
||||
names:[],
|
||||
|
@ -328,6 +332,7 @@ Base.exports.PaperScript = (function() {
|
|||
// the lines of the original code, all that is required is a
|
||||
// mappings string that increments by one between each line.
|
||||
// AACA is the instruction to increment the line by one.
|
||||
// TODO: Add support for column offsets!
|
||||
mappings: mappings.join(';AACA'),
|
||||
sourceRoot: '',
|
||||
sources: [url],
|
||||
|
@ -336,19 +341,25 @@ Base.exports.PaperScript = (function() {
|
|||
}
|
||||
// Now do the parsing magic
|
||||
walkAST(parse(code, { ranges: true }));
|
||||
if (sourceMap) {
|
||||
// Adjust the line offset of the resulting code if required.
|
||||
// This is part of a browser hack, see above.
|
||||
if (offsetCode)
|
||||
if (map) {
|
||||
if (offsetCode) {
|
||||
// Adjust the line offset of the resulting code if required.
|
||||
// This is part of a browser hack, see above.
|
||||
code = new Array(offset + 1).join('\n') + code;
|
||||
code += "\n//# sourceMappingURL=data:application/json;base64,"
|
||||
+ window.btoa(unescape(encodeURIComponent(
|
||||
JSON.stringify(sourceMap))))
|
||||
+ "\n//# sourceURL=" + (url || 'paperscript');
|
||||
if (url)
|
||||
sourceMaps[url] = sourceMap;
|
||||
}
|
||||
if (/^(inline|both)$/.test(sourceMaps)) {
|
||||
code += "\n//# sourceMappingURL=data:application/json;base64,"
|
||||
+ window.btoa(unescape(encodeURIComponent(
|
||||
JSON.stringify(map))));
|
||||
}
|
||||
code += "\n//# sourceURL=" + (url || 'paperscript');
|
||||
}
|
||||
return code;
|
||||
return {
|
||||
url: url,
|
||||
source: source,
|
||||
code: code,
|
||||
map: map
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -362,14 +373,15 @@ Base.exports.PaperScript = (function() {
|
|||
* @function
|
||||
*
|
||||
* @option options.url {String} the url of the source, for source-map
|
||||
* debugging
|
||||
* generation
|
||||
* @option options.source {String} the source to be used for the source-
|
||||
* mapping, in case the code that's passed in has already been mingled.
|
||||
*
|
||||
* @param {String} code the PaperScript code
|
||||
* @param {PaperScope} scope the scope for which the code is executed
|
||||
* @param {Object} [option] the compilation options
|
||||
* @return {String} the compiled PaperScript translated into JavaScript code
|
||||
* @return {Object} an object holding the compiled PaperScript translated
|
||||
* into JavaScript code along with source-maps and other information.
|
||||
*/
|
||||
function execute(code, scope, options) {
|
||||
// Set currently active scope.
|
||||
|
@ -393,8 +405,9 @@ Base.exports.PaperScript = (function() {
|
|||
// function call.
|
||||
params = [],
|
||||
args = [],
|
||||
func;
|
||||
code = compile(code, options);
|
||||
func,
|
||||
compiled = typeof code === 'object' ? code : compile(code, options);
|
||||
code = compiled.code;
|
||||
function expose(scope, hidden) {
|
||||
// Look through all enumerable properties on the scope and expose
|
||||
// these too as pseudo-globals, but only if they seem to be in use.
|
||||
|
@ -428,12 +441,12 @@ Base.exports.PaperScript = (function() {
|
|||
if (handlers)
|
||||
code += '\nreturn { ' + handlers + ' };';
|
||||
var agent = paper.agent;
|
||||
if (agent.chrome || agent.firefox) {
|
||||
// On Firefox, all error numbers inside dynamically compiled code
|
||||
// are relative to the line where the eval / compilation happened.
|
||||
// To fix this issue, we're temporarily inserting a new script
|
||||
// tag. We also use this on Chrome to fix an issue with compiled
|
||||
// functions:
|
||||
if (agent.chrome || agent.firefox && agent.versionNumber < 40) {
|
||||
// On older Firefox, all error numbers inside dynamically compiled
|
||||
// code are relative to the line where the eval / compilation
|
||||
// happened. To fix this issue, we're temporarily inserting a new
|
||||
// script tag.
|
||||
// We also use this on Chrome to fix issues with compiled functions:
|
||||
// https://code.google.com/p/chromium/issues/detail?id=331655
|
||||
var script = document.createElement('script'),
|
||||
head = document.head || document.getElementsByTagName('head')[0];
|
||||
|
@ -472,6 +485,7 @@ Base.exports.PaperScript = (function() {
|
|||
// Automatically update view at the end.
|
||||
view.update();
|
||||
}
|
||||
return compiled;
|
||||
}
|
||||
|
||||
function loadScript(script) {
|
||||
|
@ -562,13 +576,7 @@ Base.exports.PaperScript = (function() {
|
|||
compile: compile,
|
||||
execute: execute,
|
||||
load: load,
|
||||
parse: parse,
|
||||
sourceMapSupport: {
|
||||
retrieveSourceMap: function(source) {
|
||||
var map = sourceMaps[source];
|
||||
return map ? { url: source, map: map } : null;
|
||||
}
|
||||
}
|
||||
parse: parse
|
||||
};
|
||||
// Pass on `this` as the binding object, so we can reference Acorn both in
|
||||
// development and in the built library.
|
||||
|
|
25
src/node.js
25
src/node.js
|
@ -74,23 +74,40 @@ DOMParser.prototype.parseFromString = function(string, contenType) {
|
|||
return div.firstChild;
|
||||
};
|
||||
|
||||
var sourceMaps = {};
|
||||
var sourceMapSupport = {
|
||||
retrieveSourceMap: function(source) {
|
||||
var map = sourceMaps[source];
|
||||
return map ? { url: source, map: map } : null;
|
||||
}
|
||||
};
|
||||
|
||||
// Register the .pjs extension for automatic compilation as PaperScript
|
||||
require.extensions['.pjs'] = function(module, filename) {
|
||||
// Requiring a PaperScript on Node.js returns an initialize method which
|
||||
// needs to receive a Canvas object when called and returns the
|
||||
// PaperScope.
|
||||
module.exports = function(canvas) {
|
||||
var source = fs.readFileSync(filename, 'utf8');
|
||||
// TODO: Fix this once we can require('paper') from node specific code.
|
||||
paper.PaperScript.sourceMapSupport = sourceMapSupport;
|
||||
var source = fs.readFileSync(filename, 'utf8'),
|
||||
code = 'require("source-map-support").install(paper.PaperScript.sourceMapSupport);\n' + source,
|
||||
compiled = paper.PaperScript.compile(code, {
|
||||
url: filename,
|
||||
source: source,
|
||||
sourceMaps: true,
|
||||
offset: -1 // remove require("source-map-support")...
|
||||
}),
|
||||
scope = new paper.PaperScope();
|
||||
// Keep track of sourceMaps so retrieveSourceMap() can link them up
|
||||
scope.setup(canvas);
|
||||
scope.__filename = filename;
|
||||
scope.__dirname = path.dirname(filename);
|
||||
// Expose core methods and values
|
||||
scope.require = require;
|
||||
scope.console = console;
|
||||
paper.PaperScript.execute(source, scope, {
|
||||
url: filename
|
||||
});
|
||||
sourceMaps[filename] = compiled.map;
|
||||
paper.PaperScript.execute(compiled, scope);
|
||||
return scope;
|
||||
};
|
||||
};
|
||||
|
|
Loading…
Reference in a new issue