switch to using extracted jsdom-context-require

This commit is contained in:
Michael Rawlings 2018-06-27 14:12:41 -07:00
parent 47e2dfef0a
commit 505dd1e1ba
No known key found for this signature in database
GPG Key ID: 95A877250FE4F1FA
12 changed files with 205 additions and 389 deletions

260
package-lock.json generated
View File

@ -215,20 +215,12 @@
"dev": true
},
"acorn-globals": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/acorn-globals/-/acorn-globals-3.1.0.tgz",
"integrity": "sha1-/YJw9x+7SZawBPqIDuXUZXOnMb8=",
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/acorn-globals/-/acorn-globals-4.1.0.tgz",
"integrity": "sha512-KjZwU26uG3u6eZcfGbTULzFcsoz6pegNKtHPksZPOUsiKo5bUmiBPa38FuHZ/Eun+XYh/JCCkS9AS3Lu4McQOQ==",
"dev": true,
"requires": {
"acorn": "^4.0.4"
},
"dependencies": {
"acorn": {
"version": "4.0.13",
"resolved": "https://registry.npmjs.org/acorn/-/acorn-4.0.13.tgz",
"integrity": "sha1-EFSVrlNh1pe9GVyCUZLhrX8lN4c=",
"dev": true
}
"acorn": "^5.0.0"
}
},
"acorn-jsx": {
@ -443,6 +435,12 @@
"integrity": "sha1-GdOGodntxufByF04iu28xW0zYC0=",
"dev": true
},
"async-limiter": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/async-limiter/-/async-limiter-1.0.0.tgz",
"integrity": "sha512-jp/uFnooOiO+L211eZOoSyzpOITMXx1rBITauYykG3BRYPu8h0UcxsPNB04RR5vo4Tyz3+ay17tR6JVf9qzYWg==",
"dev": true
},
"async-writer": {
"version": "2.1.3",
"resolved": "https://registry.npmjs.org/async-writer/-/async-writer-2.1.3.tgz",
@ -849,6 +847,12 @@
"repeat-element": "^1.1.2"
}
},
"browser-process-hrtime": {
"version": "0.1.2",
"resolved": "https://registry.npmjs.org/browser-process-hrtime/-/browser-process-hrtime-0.1.2.tgz",
"integrity": "sha1-Ql1opY00R/AqBKqJQYf86K+Le44=",
"dev": true
},
"browser-refresh-client": {
"version": "1.1.4",
"resolved": "https://registry.npmjs.org/browser-refresh-client/-/browser-refresh-client-1.1.4.tgz",
@ -1209,11 +1213,14 @@
"integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==",
"dev": true
},
"content-type-parser": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/content-type-parser/-/content-type-parser-1.0.2.tgz",
"integrity": "sha512-lM4l4CnMEwOLHAHr/P6MEZwZFPJFtAAKgL6pogbXmVZggIqXhdB6RbBtPOTsw2FcXwYhehRGERJmRrjOiIB8pQ==",
"dev": true
"context-require": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/context-require/-/context-require-1.0.1.tgz",
"integrity": "sha512-QDkbK4HxLBqpzPIfpN2Ql1qxwm6Kq45BvqPd3aeOLOtiRMIcYOUoSo9r7nc+LVTuAByqeAfzLcGnBLVd6mB0/w==",
"dev": true,
"requires": {
"builtins": "^2.0.0"
}
},
"convert-source-map": {
"version": "1.5.1",
@ -1313,9 +1320,9 @@
"dev": true
},
"cssstyle": {
"version": "0.2.37",
"resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-0.2.37.tgz",
"integrity": "sha1-VBCXI0yyUTyDzu06zdwn/yeYfVQ=",
"version": "0.3.1",
"resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-0.3.1.tgz",
"integrity": "sha512-tNvaxM5blOnxanyxI6panOsnfiyLRj3HV4qjqqS45WPNS1usdYWRUQjqTEEELK73lpeP/1KoIGYUwrBn/VcECA==",
"dev": true,
"requires": {
"cssom": "0.3.x"
@ -1347,6 +1354,17 @@
}
}
},
"data-urls": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/data-urls/-/data-urls-1.0.0.tgz",
"integrity": "sha512-ai40PPQR0Fn1lD2PPie79CibnlMN2AYiDhwFX/rZHVsxbs5kNJSjegqXIprhouGXlRdEnfybva7kqRGnB6mypA==",
"dev": true,
"requires": {
"abab": "^1.0.4",
"whatwg-mimetype": "^2.0.0",
"whatwg-url": "^6.4.0"
}
},
"date-fns": {
"version": "1.29.0",
"resolved": "https://registry.npmjs.org/date-fns/-/date-fns-1.29.0.tgz",
@ -1560,6 +1578,15 @@
"integrity": "sha1-sXrtguirWeUt2cGbF1bg/BhyBMI=",
"dev": true
},
"domexception": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/domexception/-/domexception-1.0.1.tgz",
"integrity": "sha512-raigMkn7CJNNo6Ihro1fzG7wr3fHuYVytzquZKX5n0yizGsTcYgzdIUwj1X9pK0VvjeihV+XiclP+DjwbsSKug==",
"dev": true,
"requires": {
"webidl-conversions": "^4.0.2"
}
},
"domhandler": {
"version": "2.4.2",
"resolved": "https://registry.npmjs.org/domhandler/-/domhandler-2.4.2.tgz",
@ -3569,38 +3596,48 @@
"optional": true
},
"jsdom": {
"version": "9.12.0",
"resolved": "https://registry.npmjs.org/jsdom/-/jsdom-9.12.0.tgz",
"integrity": "sha1-6MVG//ywbADUgzyoRBD+1/igl9Q=",
"version": "11.11.0",
"resolved": "https://registry.npmjs.org/jsdom/-/jsdom-11.11.0.tgz",
"integrity": "sha512-ou1VyfjwsSuWkudGxb03FotDajxAto6USAlmMZjE2lc0jCznt7sBWkhfRBRaWwbnmDqdMSTKTLT5d9sBFkkM7A==",
"dev": true,
"requires": {
"abab": "^1.0.3",
"acorn": "^4.0.4",
"acorn-globals": "^3.1.0",
"abab": "^1.0.4",
"acorn": "^5.3.0",
"acorn-globals": "^4.1.0",
"array-equal": "^1.0.0",
"content-type-parser": "^1.0.1",
"cssom": ">= 0.3.2 < 0.4.0",
"cssstyle": ">= 0.2.37 < 0.3.0",
"escodegen": "^1.6.1",
"html-encoding-sniffer": "^1.0.1",
"nwmatcher": ">= 1.3.9 < 2.0.0",
"parse5": "^1.5.1",
"request": "^2.79.0",
"sax": "^1.2.1",
"symbol-tree": "^3.2.1",
"tough-cookie": "^2.3.2",
"webidl-conversions": "^4.0.0",
"whatwg-encoding": "^1.0.1",
"whatwg-url": "^4.3.0",
"xml-name-validator": "^2.0.1"
},
"dependencies": {
"acorn": {
"version": "4.0.13",
"resolved": "https://registry.npmjs.org/acorn/-/acorn-4.0.13.tgz",
"integrity": "sha1-EFSVrlNh1pe9GVyCUZLhrX8lN4c=",
"dev": true
}
"cssstyle": ">= 0.3.1 < 0.4.0",
"data-urls": "^1.0.0",
"domexception": "^1.0.0",
"escodegen": "^1.9.0",
"html-encoding-sniffer": "^1.0.2",
"left-pad": "^1.2.0",
"nwsapi": "^2.0.0",
"parse5": "4.0.0",
"pn": "^1.1.0",
"request": "^2.83.0",
"request-promise-native": "^1.0.5",
"sax": "^1.2.4",
"symbol-tree": "^3.2.2",
"tough-cookie": "^2.3.3",
"w3c-hr-time": "^1.0.1",
"webidl-conversions": "^4.0.2",
"whatwg-encoding": "^1.0.3",
"whatwg-mimetype": "^2.1.0",
"whatwg-url": "^6.4.1",
"ws": "^4.0.0",
"xml-name-validator": "^3.0.0"
}
},
"jsdom-context-require": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/jsdom-context-require/-/jsdom-context-require-1.0.1.tgz",
"integrity": "sha512-D35Rt4xFnjCUAmt1Fz+8QXECyY3CsMyT1UqFgGG24C6qT0FAhrGjQY/v3rOvBXNb8w0u6f9paM8eVe+VaKOtZw==",
"dev": true,
"requires": {
"context-require": "^1.0.1",
"jsdom": "^11.6.2",
"lasso-resolve-from": "^1.2.0"
}
},
"jsesc": {
@ -3734,6 +3771,12 @@
"integrity": "sha1-GwuP+ayceIklBYK3C3ExXZ2m2aM=",
"dev": true
},
"left-pad": {
"version": "1.3.0",
"resolved": "https://registry.npmjs.org/left-pad/-/left-pad-1.3.0.tgz",
"integrity": "sha512-XI5MPzVNApjAyhQzphX8BkmKsKUxD4LdyK24iZeQGinBN9yTQT3bFlCBy/aVx2HrNcqQGsdot8ghrjyrvMCoEA==",
"dev": true
},
"leven": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/leven/-/leven-2.1.0.tgz",
@ -4025,6 +4068,12 @@
"integrity": "sha512-UejweD1pDoXu+AD825lWwp4ZGtSwgnpZxb3JDViD7StjQz+Nb/6l093lx4OQ0foGWNRoc19mWy7BzL+UAK2iVg==",
"dev": true
},
"lodash.sortby": {
"version": "4.7.0",
"resolved": "https://registry.npmjs.org/lodash.sortby/-/lodash.sortby-4.7.0.tgz",
"integrity": "sha1-7dFMgk4sycHgsKG0K7UhBRakJDg=",
"dev": true
},
"log-driver": {
"version": "1.2.7",
"resolved": "https://registry.npmjs.org/log-driver/-/log-driver-1.2.7.tgz",
@ -4743,10 +4792,10 @@
"integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=",
"dev": true
},
"nwmatcher": {
"version": "1.4.4",
"resolved": "https://registry.npmjs.org/nwmatcher/-/nwmatcher-1.4.4.tgz",
"integrity": "sha512-3iuY4N5dhgMpCUrOVnuAdGrgxVqV2cJpM+XNccjR2DKOB1RUP0aA+wGXEiNziG/UKboFyGBIoKOaNlJxx8bciQ==",
"nwsapi": {
"version": "2.0.4",
"resolved": "https://registry.npmjs.org/nwsapi/-/nwsapi-2.0.4.tgz",
"integrity": "sha512-Zt6HRR6RcJkuj5/N9zeE7FN6YitRW//hK2wTOwX274IBphbY3Zf5+yn5mZ9v/SzAOTMjQNxZf9KkmPLWn0cV4g==",
"dev": true
},
"nyc": {
@ -6098,9 +6147,9 @@
}
},
"parse5": {
"version": "1.5.1",
"resolved": "https://registry.npmjs.org/parse5/-/parse5-1.5.1.tgz",
"integrity": "sha1-m387DeMr543CQBsXVzzK8Pb1nZQ=",
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/parse5/-/parse5-4.0.0.tgz",
"integrity": "sha512-VrZ7eOd3T1Fk4XWNXMgiGBK/z0MG48BWG2uQNU4I72fkQuKUTZpl+u9k+CxEG0twMVzSmXEEz12z5Fnw1jIQFA==",
"dev": true
},
"parseurl": {
@ -6213,6 +6262,12 @@
"integrity": "sha512-ARhBOdzS3e41FbkW/XWrTEtukqqLoK5+Z/4UeDaLuSW+39JPeFgs4gCGqsrJHVZX0fUrx//4OF0K1CUGwlIFow==",
"dev": true
},
"pn": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/pn/-/pn-1.1.0.tgz",
"integrity": "sha512-2qHaIQr2VLRFoxe2nASzsV6ef4yOOH+Fi9FBOVH6cqeSgUnoyySPZkxzLuzd+RYOQTRpROA0ztTMqxROKSb/nA==",
"dev": true
},
"posix-character-classes": {
"version": "0.1.1",
"resolved": "https://registry.npmjs.org/posix-character-classes/-/posix-character-classes-0.1.1.tgz",
@ -6730,6 +6785,26 @@
}
}
},
"request-promise-core": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/request-promise-core/-/request-promise-core-1.1.1.tgz",
"integrity": "sha1-Pu4AssWqgyOc+wTFcA2jb4HNCLY=",
"dev": true,
"requires": {
"lodash": "^4.13.1"
}
},
"request-promise-native": {
"version": "1.0.5",
"resolved": "https://registry.npmjs.org/request-promise-native/-/request-promise-native-1.0.5.tgz",
"integrity": "sha1-UoF3D2jgyXGeUWP9P6tIIhX0/aU=",
"dev": true,
"requires": {
"request-promise-core": "1.1.1",
"stealthy-require": "^1.1.0",
"tough-cookie": ">=2.3.3"
}
},
"require-uncached": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/require-uncached/-/require-uncached-1.0.3.tgz",
@ -7279,6 +7354,12 @@
"integrity": "sha512-zhSCtt8v2NDrRlPQpCNtw/heZLtfUDqxBM1udqikb/Hbk52LK4nQSwr10u77iopCW5LsyHpuXS0GnEc48mLeew==",
"dev": true
},
"stealthy-require": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/stealthy-require/-/stealthy-require-1.1.1.tgz",
"integrity": "sha1-NbCYdbT/SfJqd35QmzCQoyJr8ks=",
"dev": true
},
"string-argv": {
"version": "0.0.2",
"resolved": "https://registry.npmjs.org/string-argv/-/string-argv-0.0.2.tgz",
@ -7533,10 +7614,21 @@
}
},
"tr46": {
"version": "0.0.3",
"resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz",
"integrity": "sha1-gYT9NH2snNwYWZLzpmIuFLnZq2o=",
"dev": true
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/tr46/-/tr46-1.0.1.tgz",
"integrity": "sha1-qLE/1r/SSJUZZ0zN5VujaTtwbQk=",
"dev": true,
"requires": {
"punycode": "^2.1.0"
},
"dependencies": {
"punycode": {
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz",
"integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==",
"dev": true
}
}
},
"trim-newlines": {
"version": "1.0.0",
@ -7787,6 +7879,15 @@
}
}
},
"w3c-hr-time": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/w3c-hr-time/-/w3c-hr-time-1.0.1.tgz",
"integrity": "sha1-gqwr/2PZUOqeMYmlimViX+3xkEU=",
"dev": true,
"requires": {
"browser-process-hrtime": "^0.1.2"
}
},
"warp10": {
"version": "1.3.6",
"resolved": "https://registry.npmjs.org/warp10/-/warp10-1.3.6.tgz",
@ -7815,22 +7916,21 @@
}
}
},
"whatwg-mimetype": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-2.1.0.tgz",
"integrity": "sha512-FKxhYLytBQiUKjkYteN71fAUA3g6KpNXoho1isLiLSB3N1G4F35Q5vUxWfKFhBwi5IWF27VE6WxhrnnC+m0Mew==",
"dev": true
},
"whatwg-url": {
"version": "4.8.0",
"resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-4.8.0.tgz",
"integrity": "sha1-0pgaqRSMHgCkHFphMRZqtGg7vMA=",
"version": "6.5.0",
"resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-6.5.0.tgz",
"integrity": "sha512-rhRZRqx/TLJQWUpQ6bmrt2UV4f0HCQ463yQuONJqC6fO2VoEb1pTYddbe59SkYq87aoM5A3bdhMZiUiVws+fzQ==",
"dev": true,
"requires": {
"tr46": "~0.0.3",
"webidl-conversions": "^3.0.0"
},
"dependencies": {
"webidl-conversions": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz",
"integrity": "sha1-JFNCdeKnvGvnvIZhHMFq4KVlSHE=",
"dev": true
}
"lodash.sortby": "^4.7.0",
"tr46": "^1.0.1",
"webidl-conversions": "^4.0.2"
}
},
"which": {
@ -7862,10 +7962,20 @@
"mkdirp": "^0.5.1"
}
},
"ws": {
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/ws/-/ws-4.1.0.tgz",
"integrity": "sha512-ZGh/8kF9rrRNffkLFV4AzhvooEclrOH0xaugmqGsIfFgOE/pIz4fMc4Ef+5HSQqTEug2S9JZIWDR47duDSLfaA==",
"dev": true,
"requires": {
"async-limiter": "~1.0.0",
"safe-buffer": "~5.1.0"
}
},
"xml-name-validator": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-2.0.1.tgz",
"integrity": "sha1-TYuPHszTQZqjYgYb7O9RXh5VljU=",
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-3.0.0.tgz",
"integrity": "sha512-A5CUptxDsvxKJEU3yO6DuWBSJz/qizqzJKOMIfUJHETbBw/sFaDxgd6fxm1ewUaM0jZ444Fc5vC5ROYurg/4Pw==",
"dev": true
},
"xtend": {

View File

@ -82,7 +82,7 @@
"istanbul-lib-instrument": "^1.8.0",
"it-fails": "^1.0.0",
"jquery": "^3.1.1",
"jsdom": "^9.12.0",
"jsdom-context-require": "^1.0.1",
"lasso-resolve-from": "^1.2.0",
"lint-staged": "^7.0.0",
"marko-widgets": "^7.0.1",

View File

@ -113,7 +113,7 @@ BrowserHelpers.prototype = {
},
cleanPath: function(path) {
return path.replace(/\.\d+\.in-module-context$/, "");
return path.replace(/\.\d+\.in-context$/, "");
}
};

View File

@ -1,187 +0,0 @@
"use strict";
// Someday this will become a separate package.
const vm = require("vm");
const path = require("path");
const Module = require("module");
const builtinModules = require("builtins")();
const originalCompile = Module.prototype._compile;
const originalResolve = Module._resolveFilename;
const S_POSTFIX = Symbol("postfix");
const S_CONTEXT = Symbol("context");
const S_RESOLVE = Symbol("resolve");
const S_HOOKS = Symbol("hooks");
const EXT_NAME = ".in-module-context";
let moduleId = 0;
class ContextModule extends Module {
/**
* Custom nodejs Module implementation which uses a provided
* resolver, require hooks, and context.
*/
constructor(options) {
const postfix = "." + moduleId++ + EXT_NAME;
const filename = path.join(options.dir, "index" + postfix);
super(filename);
this.filename = filename;
this[S_POSTFIX] = postfix;
this[S_CONTEXT] = options.context;
this[S_RESOLVE] = options.resolve;
this[S_HOOKS] = options.extensions;
}
}
/**
* Patch nodejs module system to support context,
* compilation and module resolution overrides.
*/
require.extensions[EXT_NAME] = requireHook;
Module._resolveFilename = resolveFileHook;
Module.prototype._compile = compileHook;
// Expose main util.
exports.createModule = createContextModule;
/**
* Creates a custom Module object which runs all required scripts in a provided vm context.
*
* @param {object} config Config for the module.
* @param {string} config.dir The directory from which to resolve requires for this module.
* @param {*|JSDOM} config.context A vm context which will be used as the context for any required modules.
* @param {function} [config.resolve] A function to which will override the native module resolution.
* @param {Object.<string,function>} [config.extensions] An object containing any context specific require hooks to be used in this module.
* @return {ContextModule}
*/
function createContextModule(options) {
return new ContextModule(options);
}
/**
* Hijack native file resolution using closest custom resolver.
*
* @param {string} request The file to resolve.
* @param {Module} parentModule The module requiring this file.
* @return {string}
*/
function resolveFileHook(request, parentModule) {
const isNotBuiltin = builtinModules.indexOf(request) === -1;
const contextModule =
isNotBuiltin && findNearestContextModule(parentModule);
if (contextModule) {
const resolver = contextModule[S_RESOLVE];
if (resolver) {
const dir = path.dirname(parentModule.filename);
const postfix = contextModule[S_POSTFIX];
if (request.endsWith(postfix)) {
return request;
}
if (path.isAbsolute(request)) {
request = path.relative(dir, request);
if (request[0] !== ".") {
request = "./" + request;
}
}
return resolver(dir, request) + postfix;
}
}
return originalResolve(request, parentModule);
}
/**
* Require hook which removes module postfix and uses custom extensions if provided.
*
* @param {Module} module
* @param {string} filename
*/
function requireHook(module, filename) {
const contextModule = findNearestContextModule(module);
const postfix = contextModule[S_POSTFIX];
const extensions = contextModule[S_HOOKS];
filename = filename.slice(0, -postfix.length);
const ext = path.extname(filename);
const compiler =
(extensions && extensions[ext]) ||
require.extensions[ext] ||
require.extensions[".js"];
return compiler(module, filename);
}
/**
* This overrides script compilation to ensure the nearest context module is used.
*
* @param {string} content The file contents of the script.
* @param {string} filename The filename for the script.
*/
function compileHook(content, filename) {
const contextModule = findNearestContextModule(this);
if (contextModule) {
const context = contextModule[S_CONTEXT];
const script = new vm.Script(Module.wrap(content), {
filename: filename,
lineOffset: 0,
displayErrors: true
});
return runScript(context, script).call(
this.exports,
this.exports,
createRequire(this),
this,
filename,
path.dirname(filename)
);
}
return originalCompile.apply(this, arguments);
}
/**
* Walks up a module tree to find the nearest context module.
*
* @param {Module} cur The starting module.
* @return {Module?}
*/
function findNearestContextModule(cur) {
do {
if (cur instanceof ContextModule) {
return cur;
}
} while ((cur = cur.parent));
}
/**
* Helper which will run a vm script in a context.
* Special case for JSDOM where `runVMScript` is used.
*
* @param {*} context The vm context to run the script in (or a jsdom instance).
* @param {Script} script The vm script to run.
* @return {object}
*/
function runScript(context, script) {
return context.runVMScript
? context.runVMScript(script)
: script.runInContext(context);
}
/**
* Creates a require function bound to a module
* and adds a `resolve` function the same as nodejs.
*
* @param {Module} module The module to create a require function for.
* @return {function}
*/
function createRequire(module) {
const require = module.require.bind(module);
require.resolve = function(request) {
return resolveFileHook(request, module);
};
return require;
}

View File

@ -1,107 +0,0 @@
"use strict";
// Someday this will become a separate package.
const fs = require("fs");
const path = require("path");
const jsdom = require("jsdom");
// const JSDOM = require('jsdom').JSDOM; // JSDOM 10+
const browserResolve = require("lasso-resolve-from");
const createContextModule = require("./create-context-module").createModule;
const remapCache = Object.create(null);
/**
* Creates a custom Module object which runs all required scripts
* in a new jsdom instance.
*
* @param {object} config Config for the module.
* @param {string} config.dir The directory from which to resolve requires for this module.
* @param {string} config.html The initial html to parse with jsdom.
* @param {function} config.beforeParse A function called with the window, and the module, before parsing html.
* @param {Object.<string,function>} [config.extensions] An object containing any browser specific require hooks to be used in this module.
* @return {JSDOM}
*/
module.exports = function(options) {
const html = options.html;
const dir = options.dir;
const extensions = options.extensions;
const beforeParse = options.beforeParse;
options.html = options.dir = options.extensions = options.beforeParse = undefined;
const window = jsdom.jsdom("", options).defaultView;
const context = {
window: window,
runVMScript(script) {
return jsdom.evalVMScript(window, script);
}
};
// const context = new JSDOM('', options); // JSDOM 10+
// const window = context.window; // JSDOM 10+
const resolveConfig = {
remaps: loadRemaps,
extensions:
extensions &&
[]
.concat(Object.keys(require.extensions))
.concat(Object.keys(extensions))
.filter(unique)
};
const module = createContextModule({
dir: dir,
context: context,
resolve: resolve,
extensions: extensions
});
context.require = module.require.bind(module);
beforeParse && beforeParse(window, context);
window.document.open();
window.document.write(html);
return context;
/**
* A function to resolve modules in the browser using the provided config.
*
* @param {string} from The file being resolved from.
* @param {string} request The requested path to resolve.
* @return {string}
*/
function resolve(from, request) {
return browserResolve(from, request, resolveConfig).path;
}
};
/**
* Array filter for uniqueness.
*/
function unique(item, i, list) {
return list.indexOf(item) === i;
}
/**
* Loads browser.json remaps.
*
* @param {string} dir
* @return {object|void}
*/
function loadRemaps(dir) {
const file = path.join(dir, "browser.json");
if (file in remapCache) {
return remapCache[file];
}
let result;
const remaps = fs.existsSync(file) && require(file).requireRemap;
if (remaps) {
result = {};
for (const remap of remaps) {
result[path.join(dir, remap.from)] = path.join(dir, remap.to);
}
}
remapCache[file] = result;
return result;
}

View File

@ -1,7 +1,7 @@
"use strict";
const jQuery = require("jquery");
const createJSDOMModule = require("./create-jsdom-module");
const createBrowser = require("jsdom-context-require");
const compiler = require("../../compiler");
const noop = function() {};
const globals = [
@ -32,7 +32,7 @@ const browserExtensions = {
module.exports = function(dir, html, options) {
options = options || {};
return createJSDOMModule({
return createBrowser({
dir: dir,
html: html,
extensions: browserExtensions,

View File

@ -1,7 +1,7 @@
"use strict";
const createJSDOMModule = require("../__util__/create-jsdom-module");
const defaultDocument = createJSDOMModule({
const createBrowser = require("jsdom-context-require");
const defaultDocument = createBrowser({
dir: __dirname,
html: "<html><body></body></html>"
}).window.document;
@ -182,7 +182,7 @@ module.exports = function runRenderTest(dir, snapshot, done, options) {
let expectedHtmlPath = path.join(dir, "expected.html");
let html = fs.readFileSync(expectedHtmlPath, "utf-8");
let browser = createJSDOMModule({
let browser = createBrowser({
dir: __dirname,
html: "<html><body>" + html + "</body></html>"
});
@ -216,7 +216,7 @@ module.exports = function runRenderTest(dir, snapshot, done, options) {
let vdomHtml = domToHTML(actualNode);
let browser = createJSDOMModule({
let browser = createBrowser({
dir: __dirname,
html: "<html><body>" + vdomHtml + "</body></html>"
});

View File

@ -2,12 +2,12 @@
require("../__util__/test-init");
var autotest = require("../autotest");
var createJSDOMModule = require("../__util__/create-marko-jsdom-module");
var createBrowserWithMarko = require("../__util__/create-marko-jsdom-module");
var ssrTemplate = require("./template.marko");
var hydrateComponentPath = require.resolve("./template.component-browser.js");
var browserHelpersPath = require.resolve("../__util__/BrowserHelpers");
var testTargetHTML = '<div id="testsTarget"></div><div></div>';
var browser = createJSDOMModule(__dirname, testTargetHTML);
var browser = createBrowserWithMarko(__dirname, testTargetHTML);
var BrowserHelpers = browser.require(browserHelpersPath);
autotest("fixtures", {
@ -62,7 +62,7 @@ function runHydrateTest(fixture) {
ssrTemplate
.render({ components: components, $global: $global })
.then(function(html) {
var browser = createJSDOMModule(__dirname, String(html), {
var browser = createBrowserWithMarko(__dirname, String(html), {
beforeParse(window, browser) {
var marko = browser.require("marko/components");
var legacy = browser.require("marko/legacy-components");

View File

@ -4,7 +4,7 @@ require("../__util__/test-init");
var autotest = require("../autotest");
var asyncTestSuite = require("../__util__/async-test-suite");
var createJSDOMModule = require("../__util__/create-marko-jsdom-module");
var createBrowserWithMarko = require("../__util__/create-marko-jsdom-module");
autotest("fixtures", run);
autotest("fixtures-deprecated", run);
@ -19,7 +19,7 @@ function run(fixture) {
var templateFile = resolve("template.marko");
var template = require(templateFile);
return template.render({}).then(function(html) {
var browser = createJSDOMModule(__dirname, String(html), {
var browser = createBrowserWithMarko(__dirname, String(html), {
beforeParse(window, browser) {
browser.require("../../components");
browser.require(templateFile);

View File

@ -8,7 +8,7 @@ chai.config.includeStack = true;
var autotest = require("../autotest");
const fs = require("fs");
const morphdom = require("marko/morphdom");
const createJSDOMModule = require("../__util__/create-jsdom-module");
const createBrowser = require("jsdom-context-require");
autotest("fixtures", fixture => {
let test = fixture.test;
@ -22,11 +22,11 @@ autotest("fixtures", fixture => {
encoding: "utf8"
});
let fromDocument = createJSDOMModule({
let fromDocument = createBrowser({
dir: __dirname,
html: "<html><body>" + fromHTML + "</body></html>"
}).window.document;
let toDocument = createJSDOMModule({
let toDocument = createBrowser({
dir: __dirname,
html: "<html><body>" + toHTML + "</body></html>"
}).window.document;

View File

@ -4,10 +4,10 @@ require("../__util__/test-init");
var fs = require("fs");
var domToString = require("../__util__/domToString");
var createJSDOMModule = require("../__util__/create-jsdom-module");
var createBrowser = require("jsdom-context-require");
var autotest = require("../autotest");
var document = createJSDOMModule({
var document = createBrowser({
dir: __dirname,
html: "<html><body></body></html>"
}).window.document;

View File

@ -4,7 +4,7 @@ require("../__util__/test-init");
var virtualize = require("marko/runtime/vdom/vdom").___virtualize;
var fs = require("fs");
var toHTML = require("../__util__/toHTML");
var createJSDOMModule = require("../__util__/create-jsdom-module");
var createBrowser = require("jsdom-context-require");
var autotest = require("../autotest");
autotest("fixtures", fixture => {
@ -16,7 +16,7 @@ autotest("fixtures", fixture => {
if (fs.existsSync(inputPath)) {
var inputHtml = fs.readFileSync(inputPath, { encoding: "utf8" });
var document = createJSDOMModule({
var document = createBrowser({
dir: __dirname,
html: "<html><body>" + inputHtml + "</body></html>"
}).window.document;