@@ -96,7 +96,7 @@ Future<RenderResult> _renderAsync(RenderOptions options) async {
96
96
if (options.data != null ) {
97
97
result = await compileStringAsync (options.data,
98
98
nodeImporter: _parseImporter (options, start),
99
- functions: _parseFunctions (options, asynch: true ),
99
+ functions: _parseFunctions (options, start, asynch: true ),
100
100
syntax: isTruthy (options.indentedSyntax) ? Syntax .sass : null ,
101
101
style: _parseOutputStyle (options.outputStyle),
102
102
useSpaces: options.indentType != 'tab' ,
@@ -107,7 +107,7 @@ Future<RenderResult> _renderAsync(RenderOptions options) async {
107
107
} else if (options.file != null ) {
108
108
result = await compileAsync (file,
109
109
nodeImporter: _parseImporter (options, start),
110
- functions: _parseFunctions (options, asynch: true ),
110
+ functions: _parseFunctions (options, start, asynch: true ),
111
111
syntax: isTruthy (options.indentedSyntax) ? Syntax .sass : null ,
112
112
style: _parseOutputStyle (options.outputStyle),
113
113
useSpaces: options.indentType != 'tab' ,
@@ -135,7 +135,7 @@ RenderResult _renderSync(RenderOptions options) {
135
135
if (options.data != null ) {
136
136
result = compileString (options.data,
137
137
nodeImporter: _parseImporter (options, start),
138
- functions: _parseFunctions (options).cast (),
138
+ functions: _parseFunctions (options, start ).cast (),
139
139
syntax: isTruthy (options.indentedSyntax) ? Syntax .sass : null ,
140
140
style: _parseOutputStyle (options.outputStyle),
141
141
useSpaces: options.indentType != 'tab' ,
@@ -146,7 +146,7 @@ RenderResult _renderSync(RenderOptions options) {
146
146
} else if (options.file != null ) {
147
147
result = compile (file,
148
148
nodeImporter: _parseImporter (options, start),
149
- functions: _parseFunctions (options).cast (),
149
+ functions: _parseFunctions (options, start ).cast (),
150
150
syntax: isTruthy (options.indentedSyntax) ? Syntax .sass : null ,
151
151
style: _parseOutputStyle (options.outputStyle),
152
152
useSpaces: options.indentType != 'tab' ,
@@ -186,7 +186,7 @@ JsError _wrapException(Object exception) {
186
186
///
187
187
/// This is typed to always return [AsyncCallable] , but in practice it will
188
188
/// return a `List<Callable>` if [asynch] is `false` .
189
- List <AsyncCallable > _parseFunctions (RenderOptions options,
189
+ List <AsyncCallable > _parseFunctions (RenderOptions options, DateTime start,
190
190
{bool asynch = false }) {
191
191
if (options.functions == null ) return const [];
192
192
@@ -200,6 +200,8 @@ List<AsyncCallable> _parseFunctions(RenderOptions options,
200
200
'Invalid signature "${signature }": ${error .message }' , error.span);
201
201
}
202
202
203
+ var context = _contextWithOptions (options, start);
204
+
203
205
if (options.fiber != null ) {
204
206
result.add (BuiltInCallable .parsed (tuple.item1, tuple.item2, (arguments) {
205
207
var fiber = options.fiber.current;
@@ -211,7 +213,7 @@ List<AsyncCallable> _parseFunctions(RenderOptions options,
211
213
scheduleMicrotask (() => fiber.run (result));
212
214
})
213
215
];
214
- var result = Function . apply (callback as Function , jsArguments);
216
+ var result = (callback as JSFunction ). apply (context , jsArguments);
215
217
return unwrapValue (isUndefined (result)
216
218
// Run `fiber.yield()` in runZoned() so that Dart resets the current
217
219
// zone once it's done. Otherwise, interweaving fibers can leave
@@ -223,8 +225,8 @@ List<AsyncCallable> _parseFunctions(RenderOptions options,
223
225
result.add (BuiltInCallable .parsed (
224
226
tuple.item1,
225
227
tuple.item2,
226
- (arguments) => unwrapValue (Function . apply (
227
- callback as Function , arguments.map (wrapValue).toList ()))));
228
+ (arguments) => unwrapValue ((callback as JSFunction )
229
+ . apply (context , arguments.map (wrapValue).toList ()))));
228
230
} else {
229
231
result.add (AsyncBuiltInCallable .parsed (tuple.item1, tuple.item2,
230
232
(arguments) async {
@@ -233,7 +235,7 @@ List<AsyncCallable> _parseFunctions(RenderOptions options,
233
235
...arguments.map (wrapValue),
234
236
allowInterop (([Object result]) => completer.complete (result))
235
237
];
236
- var result = Function . apply (callback as Function , jsArguments);
238
+ var result = (callback as JSFunction ). apply (context , jsArguments);
237
239
return unwrapValue (
238
240
isUndefined (result) ? await completer.future : result);
239
241
}));
@@ -254,27 +256,8 @@ NodeImporter _parseImporter(RenderOptions options, DateTime start) {
254
256
importers = [options.importer as JSFunction ];
255
257
}
256
258
257
- var includePaths = List <String >.from (options.includePaths ?? []);
258
-
259
259
RenderContext context;
260
- if (importers.isNotEmpty) {
261
- context = RenderContext (
262
- options: RenderContextOptions (
263
- file: options.file,
264
- data: options.data,
265
- includePaths:
266
- ([p.current, ...includePaths]).join (isWindows ? ';' : ':' ),
267
- precision: SassNumber .precision,
268
- style: 1 ,
269
- indentType: options.indentType == 'tab' ? 1 : 0 ,
270
- indentWidth: _parseIndentWidth (options.indentWidth) ?? 2 ,
271
- linefeed: _parseLineFeed (options.linefeed).text,
272
- result: RenderResult (
273
- stats: RenderResultStats (
274
- start: start.millisecondsSinceEpoch,
275
- entry: options.file ?? 'data' ))));
276
- context.options.context = context;
277
- }
260
+ if (importers.isNotEmpty) context = _contextWithOptions (options, start);
278
261
279
262
if (options.fiber != null ) {
280
263
importers = importers.map ((importer) {
@@ -297,9 +280,32 @@ NodeImporter _parseImporter(RenderOptions options, DateTime start) {
297
280
}).toList ();
298
281
}
299
282
283
+ var includePaths = List <String >.from (options.includePaths ?? []);
300
284
return NodeImporter (context, includePaths, importers);
301
285
}
302
286
287
+ /// Creates a `this` context that contains the render options.
288
+ RenderContext _contextWithOptions (RenderOptions options, DateTime start) {
289
+ var includePaths = List <String >.from (options.includePaths ?? []);
290
+ var context = RenderContext (
291
+ options: RenderContextOptions (
292
+ file: options.file,
293
+ data: options.data,
294
+ includePaths:
295
+ ([p.current, ...includePaths]).join (isWindows ? ';' : ':' ),
296
+ precision: SassNumber .precision,
297
+ style: 1 ,
298
+ indentType: options.indentType == 'tab' ? 1 : 0 ,
299
+ indentWidth: _parseIndentWidth (options.indentWidth) ?? 2 ,
300
+ linefeed: _parseLineFeed (options.linefeed).text,
301
+ result: RenderResult (
302
+ stats: RenderResultStats (
303
+ start: start.millisecondsSinceEpoch,
304
+ entry: options.file ?? 'data' ))));
305
+ context.options.context = context;
306
+ return context;
307
+ }
308
+
303
309
/// Parse [style] into an [OutputStyle] .
304
310
OutputStyle _parseOutputStyle (String style) {
305
311
if (style == null || style == 'expanded' ) return OutputStyle .expanded;
0 commit comments