mirror of
https://github.com/danog/dart-sass.git
synced 2025-01-22 22:02:00 +01:00
Clone CSS after importing it
This commit is contained in:
parent
11c95900c8
commit
d6f319f5b4
@ -4,6 +4,7 @@
|
||||
|
||||
import 'dart:async';
|
||||
|
||||
import 'package:path/path.dart' as p;
|
||||
import 'package:source_span/source_span.dart';
|
||||
|
||||
import 'ast/css.dart';
|
||||
@ -621,6 +622,8 @@ class AsyncEnvironment {
|
||||
|
||||
/// A module that represents the top-level members defined in an [Environment].
|
||||
class _EnvironmentModule implements AsyncModule {
|
||||
Uri get url => css.span.sourceUrl;
|
||||
|
||||
final List<AsyncModule> upstream;
|
||||
final Map<String, Value> variables;
|
||||
final Map<String, AstNode> variableNodes;
|
||||
@ -666,4 +669,6 @@ class _EnvironmentModule implements AsyncModule {
|
||||
return _EnvironmentModule(
|
||||
_environment, newCssAndExtender.item1, newCssAndExtender.item2);
|
||||
}
|
||||
|
||||
String toString() => p.prettyUri(css.span.sourceUrl);
|
||||
}
|
||||
|
@ -12,6 +12,12 @@ import 'value.dart';
|
||||
|
||||
/// The interface for a Sass module.
|
||||
abstract class AsyncModule {
|
||||
/// The canonical URL for this module's source file.
|
||||
///
|
||||
/// This may be `null` if the module was loaded from a string without a URL
|
||||
/// provided.
|
||||
Uri get url;
|
||||
|
||||
/// Modules that this module uses.
|
||||
List<AsyncModule> get upstream;
|
||||
|
||||
|
@ -5,10 +5,11 @@
|
||||
// DO NOT EDIT. This file was generated from async_environment.dart.
|
||||
// See tool/synchronize.dart for details.
|
||||
//
|
||||
// Checksum: 36876e7e932a30409d59d0fa256ad02d25934aab
|
||||
// Checksum: 097eb94cd15103bf4bef739a61e61414db4b55b1
|
||||
//
|
||||
// ignore_for_file: unused_import
|
||||
|
||||
import 'package:path/path.dart' as p;
|
||||
import 'package:source_span/source_span.dart';
|
||||
|
||||
import 'ast/css.dart';
|
||||
@ -623,6 +624,8 @@ class Environment {
|
||||
|
||||
/// A module that represents the top-level members defined in an [Environment].
|
||||
class _EnvironmentModule implements Module {
|
||||
Uri get url => css.span.sourceUrl;
|
||||
|
||||
final List<Module> upstream;
|
||||
final Map<String, Value> variables;
|
||||
final Map<String, AstNode> variableNodes;
|
||||
@ -668,4 +671,6 @@ class _EnvironmentModule implements Module {
|
||||
return _EnvironmentModule(
|
||||
_environment, newCssAndExtender.item1, newCssAndExtender.item2);
|
||||
}
|
||||
|
||||
String toString() => p.prettyUri(css.span.sourceUrl);
|
||||
}
|
||||
|
@ -398,6 +398,7 @@ class Extender {
|
||||
Map<SimpleSelector, Map<ComplexSelector, Extension>> newExtensions;
|
||||
|
||||
for (var extender in extenders) {
|
||||
if (extender.isEmpty) continue;
|
||||
extender._extensions.forEach((target, newSources) {
|
||||
// Private selectors can't be extended across module boundaries.
|
||||
if (target is PlaceholderSelector && target.isPrivate) return;
|
||||
|
@ -5,7 +5,7 @@
|
||||
// DO NOT EDIT. This file was generated from async_module.dart.
|
||||
// See tool/synchronize.dart for details.
|
||||
//
|
||||
// Checksum: e85903dbb32318c558ca4132a78dca55ee617280
|
||||
// Checksum: 895440529b78f1ef2830cf105af00dba0755e947
|
||||
//
|
||||
// ignore_for_file: unused_import
|
||||
|
||||
@ -19,6 +19,12 @@ import 'value.dart';
|
||||
|
||||
/// The interface for a Sass module.
|
||||
abstract class Module {
|
||||
/// The canonical URL for this module's source file.
|
||||
///
|
||||
/// This may be `null` if the module was loaded from a string without a URL
|
||||
/// provided.
|
||||
Uri get url;
|
||||
|
||||
/// Modules that this module uses.
|
||||
List<Module> get upstream;
|
||||
|
||||
|
@ -439,7 +439,10 @@ class _EvaluateVisitor
|
||||
/// modules transitively used by [root].
|
||||
///
|
||||
/// This also applies each module's extensions to its upstream modules.
|
||||
CssStylesheet _combineCss(AsyncModule root) {
|
||||
///
|
||||
/// If [clone] is `true`, this will copy the modules before extending them so
|
||||
/// that they don't modify [root] or its dependencies.
|
||||
CssStylesheet _combineCss(AsyncModule root, {bool clone = false}) {
|
||||
// TODO(nweiz): short-circuit if no upstream modules (transitively) include
|
||||
// any CSS.
|
||||
if (root.upstream.isEmpty) {
|
||||
@ -454,6 +457,9 @@ class _EvaluateVisitor
|
||||
}
|
||||
|
||||
var sortedModules = _topologicalModules(root);
|
||||
if (clone) {
|
||||
sortedModules = sortedModules.map((module) => module.cloneCss()).toList();
|
||||
}
|
||||
_extendModules(sortedModules);
|
||||
|
||||
// The imports (and comments between them) that should be included at the
|
||||
@ -476,11 +482,11 @@ class _EvaluateVisitor
|
||||
/// Extends the selectors in each module with the extensions defined in
|
||||
/// downstream modules.
|
||||
void _extendModules(List<AsyncModule> sortedModules) {
|
||||
// All the extenders directly downstream of a given module. It's important
|
||||
// that we create this in topological order, so that by the time we're
|
||||
// processing a module we've already filled in all its downstream extenders
|
||||
// and we can use them to extend that module.
|
||||
var downstreamExtenders = <AsyncModule, List<Extender>>{};
|
||||
// All the extenders directly downstream of a given module (indexed by its
|
||||
// canonical URL). It's important that we create this in topological order,
|
||||
// so that by the time we're processing a module we've already filled in all
|
||||
// its downstream extenders and we can use them to extend that module.
|
||||
var downstreamExtenders = <Uri, List<Extender>>{};
|
||||
|
||||
/// Extensions that haven't yet been satisfied by some upstream module. This
|
||||
/// adds extensions when they're defined but not satisfied, and removes them
|
||||
@ -498,13 +504,13 @@ class _EvaluateVisitor
|
||||
unsatisfiedExtensions.addAll(module.extender.extensionsWhereTarget(
|
||||
(target) => !originalSelectors.contains(target)));
|
||||
|
||||
var extenders = downstreamExtenders[module];
|
||||
var extenders = downstreamExtenders[module.url];
|
||||
if (extenders != null) module.extender.addExtensions(extenders);
|
||||
if (module.extender.isEmpty) continue;
|
||||
|
||||
for (var upstream in module.upstream) {
|
||||
downstreamExtenders
|
||||
.putIfAbsent(upstream, () => [])
|
||||
.putIfAbsent(upstream.url, () => [])
|
||||
.add(module.extender);
|
||||
}
|
||||
|
||||
@ -1026,7 +1032,9 @@ class _EvaluateVisitor
|
||||
// the CSS from modules used by [stylesheet].
|
||||
var module = environment.toModule(
|
||||
CssStylesheet(const [], stylesheet.span), Extender.empty);
|
||||
if (module.transitivelyContainsCss) await _combineCss(module).accept(this);
|
||||
if (module.transitivelyContainsCss) {
|
||||
await _combineCss(module, clone: true).accept(this);
|
||||
}
|
||||
|
||||
var visitor = _ImportedCssVisitor(this);
|
||||
for (var child in children) {
|
||||
|
@ -5,7 +5,7 @@
|
||||
// DO NOT EDIT. This file was generated from async_evaluate.dart.
|
||||
// See tool/synchronize.dart for details.
|
||||
//
|
||||
// Checksum: c7d7b5c49b3b2d09edd180440fc10582f53fdafb
|
||||
// Checksum: 0f4f00db38a7f2a60771d3d50652cbfdeb322e52
|
||||
//
|
||||
// ignore_for_file: unused_import
|
||||
|
||||
@ -447,7 +447,10 @@ class _EvaluateVisitor
|
||||
/// modules transitively used by [root].
|
||||
///
|
||||
/// This also applies each module's extensions to its upstream modules.
|
||||
CssStylesheet _combineCss(Module root) {
|
||||
///
|
||||
/// If [clone] is `true`, this will copy the modules before extending them so
|
||||
/// that they don't modify [root] or its dependencies.
|
||||
CssStylesheet _combineCss(Module root, {bool clone = false}) {
|
||||
// TODO(nweiz): short-circuit if no upstream modules (transitively) include
|
||||
// any CSS.
|
||||
if (root.upstream.isEmpty) {
|
||||
@ -462,6 +465,9 @@ class _EvaluateVisitor
|
||||
}
|
||||
|
||||
var sortedModules = _topologicalModules(root);
|
||||
if (clone) {
|
||||
sortedModules = sortedModules.map((module) => module.cloneCss()).toList();
|
||||
}
|
||||
_extendModules(sortedModules);
|
||||
|
||||
// The imports (and comments between them) that should be included at the
|
||||
@ -484,11 +490,11 @@ class _EvaluateVisitor
|
||||
/// Extends the selectors in each module with the extensions defined in
|
||||
/// downstream modules.
|
||||
void _extendModules(List<Module> sortedModules) {
|
||||
// All the extenders directly downstream of a given module. It's important
|
||||
// that we create this in topological order, so that by the time we're
|
||||
// processing a module we've already filled in all its downstream extenders
|
||||
// and we can use them to extend that module.
|
||||
var downstreamExtenders = <Module, List<Extender>>{};
|
||||
// All the extenders directly downstream of a given module (indexed by its
|
||||
// canonical URL). It's important that we create this in topological order,
|
||||
// so that by the time we're processing a module we've already filled in all
|
||||
// its downstream extenders and we can use them to extend that module.
|
||||
var downstreamExtenders = <Uri, List<Extender>>{};
|
||||
|
||||
/// Extensions that haven't yet been satisfied by some upstream module. This
|
||||
/// adds extensions when they're defined but not satisfied, and removes them
|
||||
@ -506,13 +512,13 @@ class _EvaluateVisitor
|
||||
unsatisfiedExtensions.addAll(module.extender.extensionsWhereTarget(
|
||||
(target) => !originalSelectors.contains(target)));
|
||||
|
||||
var extenders = downstreamExtenders[module];
|
||||
var extenders = downstreamExtenders[module.url];
|
||||
if (extenders != null) module.extender.addExtensions(extenders);
|
||||
if (module.extender.isEmpty) continue;
|
||||
|
||||
for (var upstream in module.upstream) {
|
||||
downstreamExtenders
|
||||
.putIfAbsent(upstream, () => [])
|
||||
.putIfAbsent(upstream.url, () => [])
|
||||
.add(module.extender);
|
||||
}
|
||||
|
||||
@ -1029,7 +1035,9 @@ class _EvaluateVisitor
|
||||
// the CSS from modules used by [stylesheet].
|
||||
var module = environment.toModule(
|
||||
CssStylesheet(const [], stylesheet.span), Extender.empty);
|
||||
if (module.transitivelyContainsCss) _combineCss(module).accept(this);
|
||||
if (module.transitivelyContainsCss) {
|
||||
_combineCss(module, clone: true).accept(this);
|
||||
}
|
||||
|
||||
var visitor = _ImportedCssVisitor(this);
|
||||
for (var child in children) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user