From 29de03dc3023d730270f0b5b989a2137b40bef0b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=BCrg=20Lehni?= Date: Mon, 20 Mar 2017 12:38:52 +0100 Subject: [PATCH] Node.js: Add code to handle separate shim modules. 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 --- src/export.js | 3 ++- src/node/canvas.js | 13 +++++++---- src/node/self.js | 57 ++++++++++++++++++---------------------------- src/node/xml.js | 40 ++++++++++++++++++++++++++++++++ 4 files changed, 72 insertions(+), 41 deletions(-) create mode 100644 src/node/xml.js diff --git a/src/export.js b/src/export.js index 6b9358ea..25e879f7 100644 --- a/src/export.js +++ b/src/export.js @@ -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) { diff --git a/src/node/canvas.js b/src/node/canvas.js index 420e5c81..e4232195 100644 --- a/src/node/canvas.js +++ b/src/node/canvas.js @@ -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'); @@ -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', { diff --git a/src/node/self.js b/src/node/self.js index 0fa37c2c..74a5f490 100644 --- a/src/node/self.js +++ b/src/node/self.js @@ -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('', { @@ -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('(<|