@@ -8,8 +8,6 @@ namespace AngleSharp.Js
88 using Jint . Native . Object ;
99 using System ;
1010 using System . Collections . Generic ;
11- using System . IO ;
12- using System . Linq ;
1311 using System . Reflection ;
1412
1513 sealed class EngineInstance
@@ -21,25 +19,19 @@ sealed class EngineInstance
2119 private readonly ReferenceCache _references ;
2220 private readonly IEnumerable < Assembly > _libs ;
2321 private readonly DomNodeInstance _window ;
24- private readonly IResourceLoader _resourceLoader ;
25- private readonly IElement _scriptElement ;
26- private readonly string _documentUrl ;
22+ private readonly JsImportMap _importMap ;
2723
2824 #endregion
2925
3026 #region ctor
3127
3228 public EngineInstance ( IWindow window , IDictionary < String , Object > assignments , IEnumerable < Assembly > libs )
3329 {
34- _resourceLoader = window . Document . Context . GetService < IResourceLoader > ( ) ;
35-
36- _scriptElement = window . Document . CreateElement ( TagNames . Script ) ;
37-
38- _documentUrl = window . Document . Url ;
30+ _importMap = new JsImportMap ( ) ;
3931
4032 _engine = new Engine ( ( options ) =>
4133 {
42- options . EnableModules ( new JsModuleLoader ( this , _documentUrl , false ) ) ;
34+ options . EnableModules ( new JsModuleLoader ( this , window . Document , false ) ) ;
4335 } ) ;
4436 _prototypes = new PrototypeCache ( _engine ) ;
4537 _references = new ReferenceCache ( ) ;
@@ -81,6 +73,8 @@ public EngineInstance(IWindow window, IDictionary<String, Object> assignments, I
8173
8274 public Engine Jint => _engine ;
8375
76+ public JsImportMap ImportMap => _importMap ;
77+
8478 #endregion
8579
8680 #region Methods
@@ -89,7 +83,7 @@ public EngineInstance(IWindow window, IDictionary<String, Object> assignments, I
8983
9084 public ObjectInstance GetDomPrototype ( Type type ) => _prototypes . GetOrCreate ( type , CreatePrototype ) ;
9185
92- public JsValue RunScript ( String source , String type , JsValue context )
86+ public JsValue RunScript ( String source , String type , String sourceUrl , JsValue context )
9387 {
9488 if ( string . IsNullOrEmpty ( type ) )
9589 {
@@ -109,7 +103,7 @@ public JsValue RunScript(String source, String type, JsValue context)
109103 else if ( type . Isi ( "module" ) )
110104 {
111105 // use a unique specifier to import the module into Jint
112- var specifier = Guid . NewGuid ( ) . ToString ( ) ;
106+ var specifier = sourceUrl ?? Guid . NewGuid ( ) . ToString ( ) ;
113107
114108 return ImportModule ( specifier , source ) ;
115109 }
@@ -124,59 +118,52 @@ private JsValue LoadImportMap(String source)
124118 {
125119 var importMap = _engine . Evaluate ( $ "JSON.parse('{ source } ')") . AsObject ( ) ;
126120
127- // get list of imports based on any scoped imports for the current document path, and any global imports
128- var moduleImports = new Dictionary < string , string > ( ) ;
129- var documentPathName = Url . Create ( _documentUrl ) . PathName . ToLower ( ) ;
130-
131121 if ( importMap . TryGetValue ( "scopes" , out var scopes ) )
132122 {
133123 var scopesObj = scopes . AsObject ( ) ;
134124
135- var scopePaths = scopesObj . GetOwnPropertyKeys ( ) . Select ( k => k . AsString ( ) ) . OrderByDescending ( k => k . Length ) ;
136-
137- foreach ( var scopePath in scopePaths )
125+ foreach ( var scopeProperty in scopesObj . GetOwnProperties ( ) )
138126 {
139- if ( ! documentPathName . Contains ( scopePath . ToLower ( ) ) )
127+ var scopePath = scopeProperty . Key . AsString ( ) ;
128+
129+ if ( _importMap . Scopes . ContainsKey ( scopePath ) )
140130 {
141131 continue ;
142132 }
143133
144- var scopeImports = scopesObj [ scopePath ] . AsObject ( ) ;
134+ var scopeValue = new Dictionary < string , Uri > ( ) ;
145135
146- var scopeImportImportSpecifiers = scopeImports . GetOwnPropertyKeys ( ) . Select ( k => k . AsString ( ) ) ;
136+ var scopeImports = scopesObj [ scopePath ] . AsObject ( ) ;
147137
148- foreach ( var scopeImportSpecifier in scopeImportImportSpecifiers )
138+ foreach ( var scopeImportProperty in scopeImports . GetOwnProperties ( ) )
149139 {
150- if ( ! moduleImports . ContainsKey ( scopeImportSpecifier ) )
140+ var scopeImportSpecifier = scopeImportProperty . Key . AsString ( ) ;
141+
142+ if ( ! scopeValue . ContainsKey ( scopeImportSpecifier ) )
151143 {
152- moduleImports . Add ( scopeImportSpecifier , scopeImports [ scopeImportSpecifier ] . AsString ( ) ) ;
144+ scopeValue . Add ( scopeImportSpecifier , new Uri ( scopeImports [ scopeImportSpecifier ] . AsString ( ) , UriKind . RelativeOrAbsolute ) ) ;
153145 }
154146 }
147+
148+ _importMap . Scopes . Add ( scopePath , scopeValue ) ;
155149 }
156150 }
157151
158152 if ( importMap . TryGetValue ( "imports" , out var imports ) )
159153 {
160154 var importsObj = imports . AsObject ( ) ;
161155
162- var importSpecifiers = importsObj . GetOwnPropertyKeys ( ) . Select ( k => k . AsString ( ) ) ;
163-
164- foreach ( var importSpecifier in importSpecifiers )
156+ foreach ( var importProperty in importsObj . GetOwnProperties ( ) )
165157 {
166- if ( ! moduleImports . ContainsKey ( importSpecifier ) )
158+ var importSpecifier = importProperty . Key . AsString ( ) ;
159+
160+ if ( ! _importMap . Imports . ContainsKey ( importSpecifier ) )
167161 {
168- moduleImports . Add ( importSpecifier , importsObj [ importSpecifier ] . AsString ( ) ) ;
162+ _importMap . Imports . Add ( importSpecifier , new Uri ( importsObj [ importSpecifier ] . AsString ( ) , UriKind . RelativeOrAbsolute ) ) ;
169163 }
170164 }
171165 }
172166
173- foreach ( var import in moduleImports )
174- {
175- var moduleContent = FetchModule ( new Uri ( import . Value , UriKind . RelativeOrAbsolute ) ) ;
176-
177- ImportModule ( import . Key , moduleContent ) ;
178- }
179-
180167 return JsValue . Undefined ;
181168 }
182169
@@ -188,34 +175,6 @@ private JsValue ImportModule(String specifier, String source)
188175 return JsValue . Undefined ;
189176 }
190177
191- public string FetchModule ( Uri moduleUrl )
192- {
193- if ( _resourceLoader == null )
194- {
195- return string . Empty ;
196- }
197-
198- if ( ! moduleUrl . IsAbsoluteUri )
199- {
200- moduleUrl = new Uri ( new Uri ( _documentUrl ) , moduleUrl ) ;
201- }
202-
203- var importUrl = Url . Convert ( moduleUrl ) ;
204-
205- var request = new ResourceRequest ( _scriptElement , importUrl ) ;
206-
207- var response = _resourceLoader . FetchAsync ( request ) . Task . Result ;
208-
209- string content ;
210-
211- using ( var streamReader = new StreamReader ( response . Content ) )
212- {
213- content = streamReader . ReadToEnd ( ) ;
214- }
215-
216- return content ;
217- }
218-
219178 #endregion
220179
221180 #region Helpers
0 commit comments