99
1010var FakeTimers = require ( './lib/FakeTimers' ) ;
1111var utils = require ( './lib/utils' ) ;
12- var vm = require ( 'vm' ) ;
12+
13+ var USE_JSDOM_EVAL = false ;
1314
1415function JSDomEnvironment ( config ) {
1516 // We lazily require jsdom because it takes a good ~.5s to load.
@@ -19,7 +20,13 @@ function JSDomEnvironment(config) {
1920 // a workerpool parent), this is the best way to ensure we only spend time
2021 // require()ing this when necessary.
2122 var jsdom = require ( './lib/jsdom-compat' ) ;
22- this . document = jsdom . jsdom ( ) ;
23+ this . document = jsdom . jsdom ( /* markup */ undefined , {
24+ resourceLoader : this . _fetchExternalResource . bind ( this ) ,
25+ features : {
26+ FetchExternalResources : [ 'script' ] ,
27+ ProcessExternalResources : [ 'script' ] ,
28+ } ,
29+ } ) ;
2330 this . global = this . document . defaultView ;
2431
2532 // Node's error-message stack size is limited at 10, but it's pretty useful to
@@ -94,17 +101,40 @@ JSDomEnvironment.prototype.dispose = function() {
94101} ;
95102
96103/**
97- * Evaluates the given source text as if it were in a file with the given name
98- * and returns the result .
104+ * Evaluates the given source text as if it were in a file with the given name.
105+ * This method returns nothing .
99106 */
100107JSDomEnvironment . prototype . runSourceText = function ( sourceText , fileName ) {
101- // TODO: Stop using the private API and instead configure jsdom with a
102- // resource loader and insert <script src="${filename}"> in the document. The
103- // reason we use vm for now is because the script element technique is slow.
104- return vm . runInContext ( sourceText , this . document . _ownerDocument . _global , {
105- filename : fileName ,
106- displayErrors : false ,
107- } ) ;
108+ if ( ! USE_JSDOM_EVAL ) {
109+ var vm = require ( 'vm' ) ;
110+ vm . runInContext ( sourceText , this . document . _ownerDocument . _global , {
111+ filename : fileName ,
112+ displayErrors : false ,
113+ } ) ;
114+ return ;
115+ }
116+
117+ // We evaluate code by inserting <script src="${filename}"> into the document
118+ // and using jsdom's resource loader to simulate serving the source code.
119+ this . _scriptToServe = sourceText ;
120+
121+ var scriptElement = this . document . createElement ( 'script' ) ;
122+ scriptElement . src = fileName ;
123+
124+ this . document . head . appendChild ( scriptElement ) ;
125+ this . document . head . removeChild ( scriptElement ) ;
126+ } ;
127+
128+ JSDomEnvironment . prototype . _fetchExternalResource = function (
129+ resource ,
130+ callback
131+ ) {
132+ var content = this . _scriptToServe ;
133+ delete this . _scriptToServe ;
134+ if ( content === null || content === undefined ) {
135+ var error = new Error ( 'Unable to find source for ' + resource . url . href ) ;
136+ }
137+ callback ( error , content ) ;
108138} ;
109139
110140JSDomEnvironment . prototype . runWithRealTimers = function ( cb ) {
0 commit comments