Skip to content

Commit

Permalink
Node.js: Add code to handle separate shim modules.
Browse files Browse the repository at this point in the history
Planend are the modules paper-jsdom and paper-jsdom-canvas, as shim modules that require and handle the dependencies as peer dependencies.

Relates to #1252
  • Loading branch information
lehni committed Mar 20, 2017
1 parent 48e9ef6 commit 29de03d
Show file tree
Hide file tree
Showing 4 changed files with 72 additions and 41 deletions.
3 changes: 2 additions & 1 deletion src/export.js
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,9 @@ paper = new (PaperScope.inject(Base.exports, {
// If we're on node, require some additional functionality now before finishing:
// - PaperScript support in require() with sourceMaps
// - exportFrames / exportImage on CanvasView
if (paper.agent.node)
if (paper.agent.node) {
require('./node/extend.js')(paper);
}

// https://github.com/umdjs/umd
if (typeof define === 'function' && define.amd) {
Expand Down
13 changes: 8 additions & 5 deletions src/node/canvas.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
// - Various Node Canvas methods, routed through from HTMLCanvasElement:
// toBuffer, pngStream, createPNGStream, jpgStream, createJPGStream

module.exports = function(self) {
module.exports = function(self, requireName) {
var Canvas;
try {
Canvas = require('canvas');
Expand All @@ -26,13 +26,16 @@ module.exports = function(self) {
// - On Node.js, it basically means the canvas is missing or not working
// which can be treated the same way.
delete self.window;
console.info(
'Canvas module not found, running in a headless context.');
// Check the required module's name to see if it contains canvas, and
// only complain about its lack if the module requires it.
if (/\bcanvas\b/.test(requireName)) {
throw new Error('Unable to load canvas module.');
}
return;
}

var idlUtils = require('jsdom/lib/jsdom/living/generated/utils'),
HTMLCanvasElement = self.HTMLCanvasElement;
var HTMLCanvasElement = self.HTMLCanvasElement,
idlUtils = require('jsdom/lib/jsdom/living/generated/utils');

// Add fake HTMLCanvasElement#type property:
Object.defineProperty(HTMLCanvasElement.prototype, 'type', {
Expand Down
57 changes: 22 additions & 35 deletions src/node/self.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,28 @@
// Node.js emulation layer of browser environment, based on jsdom with node-
// canvas integration.

var self;
var path = require('path');
// Determine the name by which name the module was required (either 'paper',
// 'paper-jsdom' or 'paper-jsdom-canvas'), and use this to determine if error
// exceptions should be thrown or if loading should fail silently.
var parent = module.parent.parent,
requireName = parent && path.basename(path.dirname(parent.filename));
requireName = /^paper/.test(requireName) ? requireName : 'paper';

var jsdom,
self;

try {
var jsdom = require('jsdom');
jsdom = require('jsdom');
} catch(e) {
// Check the required module's name to see if it contains jsdom, and only
// complain about its lack if the module requires it.
if (/\bjsdom\b/.test(requireName)) {
throw new Error('Unable to load jsdom module.');
}
}

if (jsdom) {
// Create our document and window objects through jsdom.
/* global document:true, window:true */
var document = jsdom.jsdom('<html><body></body></html>', {
Expand All @@ -29,39 +46,9 @@ try {
}
});
self = document.defaultView;

require('./canvas.js')(self);

// Define XMLSerializer shim, to emulate browser behavior.
// Effort to bring XMLSerializer to jsdom:
// https://github.com/tmpvar/jsdom/issues/1368
/*jshint -W082 */
function XMLSerializer() {
}

XMLSerializer.prototype.serializeToString = function(node) {
if (!node)
return '';
// Fix a jsdom issue where all SVG tagNames are lowercased:
// https://github.com/tmpvar/jsdom/issues/620
var text = node.outerHTML,
tagNames = ['linearGradient', 'radialGradient', 'clipPath',
'textPath'];
for (var i = 0, l = tagNames.length; i < l; i++) {
var tagName = tagNames[i];
text = text.replace(
new RegExp('(<|</)' + tagName.toLowerCase() + '\\b', 'g'),
function(match, start) {
return start + tagName;
});
}
return text;
};

self.XMLSerializer = XMLSerializer;
} catch(e) {
console.info(
'JSDom module not found, running in a headless context without DOM.');
require('./canvas.js')(self, requireName);
require('./xml.js')(self);
} else {
self = {
navigator: {
userAgent: 'Node.js (' + process.platform + '; U; rv:' +
Expand Down
40 changes: 40 additions & 0 deletions src/node/xml.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
/*
* Paper.js - The Swiss Army Knife of Vector Graphics Scripting.
* http://paperjs.org/
*
* Copyright (c) 2011 - 2016, Juerg Lehni & Jonathan Puckey
* http://scratchdisk.com/ & http://jonathanpuckey.com/
*
* Distributed under the MIT license. See LICENSE file for details.
*
* All rights reserved.
*/

module.exports = function(self) {
// Define XMLSerializer shim, to emulate browser behavior.
// Effort to bring XMLSerializer to jsdom:
// https://github.com/tmpvar/jsdom/issues/1368
self.XMLSerializer = function XMLSerializer() {
};

self.XMLSerializer.prototype = {
serializeToString: function(node) {
if (!node)
return '';
// Fix a jsdom issue where all SVG tagNames are lowercased:
// https://github.com/tmpvar/jsdom/issues/620
var text = node.outerHTML,
tagNames = ['linearGradient', 'radialGradient', 'clipPath',
'textPath'];
for (var i = 0, l = tagNames.length; i < l; i++) {
var tagName = tagNames[i];
text = text.replace(
new RegExp('(<|</)' + tagName.toLowerCase() + '\\b', 'g'),
function(match, start) {
return start + tagName;
});
}
return text;
}
};
};

0 comments on commit 29de03d

Please sign in to comment.