Skip to content

Commit

Permalink
Add a --charset flag and API option (#644)
Browse files Browse the repository at this point in the history
The automatic @charset adding is useful in general, but there are
consistently cases where it trips up naïve downstream tools. This
option makes it easier for users to control when it occurs.
  • Loading branch information
nex3 authored Apr 8, 2019
1 parent 59800ad commit 3b3a43a
Show file tree
Hide file tree
Showing 10 changed files with 210 additions and 25 deletions.
13 changes: 12 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
## 1.17.5
## 1.18.0

* Avoid recursively listing directories when finding the canonical name of a
file on case-insensitive filesystems.
Expand All @@ -7,8 +7,19 @@

* Don't claim that "package:" URLs aren't supported when they actually are.

### Command-Line Interface

* Add a `--no-charset` flag. If this flag is set, Sass will never emit a
`@charset` declaration or a byte-order mark, even if the CSS file contains
non-ASCII characters.

### Dart API

* Add a `charset` option to `compile()`, `compileString()`, `compileAsync()` and
`compileStringAsync()`. If this option is set to `false`, Sass will never emit
a `@charset` declaration or a byte-order mark, even if the CSS file contains
non-ASCII characters.

* Explicitly require that importers' `canonicalize()` methods be able to take
paths relative to their outputs as valid inputs. This isn't considered a
breaking change because the importer infrastructure already required this in
Expand Down
28 changes: 24 additions & 4 deletions lib/sass.dart
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,13 @@ export 'src/visitor/serialize.dart' show OutputStyle;
///
/// [`source_maps`]: https://pub.dartlang.org/packages/source_maps
///
/// If [charset] is `true`, this will include a `@charset` declaration or a
/// UTF-8 [byte-order mark][] if the stylesheet contains any non-ASCII
/// characters. Otherwise, it will never include a `@charset` declaration or a
/// byte-order mark.
///
/// [byte-order mark]: https://en.wikipedia.org/wiki/Byte_order_mark#UTF-8
///
/// This parameter is meant to be used as an out parameter, so that users who
/// want access to the source map can get it. For example:
///
Expand All @@ -87,7 +94,8 @@ String compile(String path,
SyncPackageResolver packageResolver,
Iterable<Callable> functions,
OutputStyle style,
void sourceMap(SingleMapping map)}) {
void sourceMap(SingleMapping map),
bool charset = true}) {
logger ??= Logger.stderr(color: color);
var result = c.compile(path,
logger: logger,
Expand All @@ -97,7 +105,8 @@ String compile(String path,
packageResolver: packageResolver),
functions: functions,
style: style,
sourceMap: sourceMap != null);
sourceMap: sourceMap != null,
charset: charset);
if (sourceMap != null) sourceMap(result.sourceMap);
return result.css;
}
Expand Down Expand Up @@ -149,6 +158,13 @@ String compile(String path,
///
/// [`source_maps`]: https://pub.dartlang.org/packages/source_maps
///
/// If [charset] is `true`, this will include a `@charset` declaration or a
/// UTF-8 [byte-order mark][] if the stylesheet contains any non-ASCII
/// characters. Otherwise, it will never include a `@charset` declaration or a
/// byte-order mark.
///
/// [byte-order mark]: https://en.wikipedia.org/wiki/Byte_order_mark#UTF-8
///
/// This parameter is meant to be used as an out parameter, so that users who
/// want access to the source map can get it. For example:
///
Expand All @@ -170,6 +186,7 @@ String compileString(String source,
Importer importer,
url,
void sourceMap(SingleMapping map),
bool charset = true,
@Deprecated("Use syntax instead.") bool indented = false}) {
logger ??= Logger.stderr(color: color);
var result = c.compileString(source,
Expand All @@ -183,7 +200,8 @@ String compileString(String source,
style: style,
importer: importer,
url: url,
sourceMap: sourceMap != null);
sourceMap: sourceMap != null,
charset: charset);
if (sourceMap != null) sourceMap(result.sourceMap);
return result.css;
}
Expand Down Expand Up @@ -233,6 +251,7 @@ Future<String> compileStringAsync(String source,
AsyncImporter importer,
url,
void sourceMap(SingleMapping map),
bool charset = true,
@Deprecated("Use syntax instead.") bool indented = false}) async {
logger ??= Logger.stderr(color: color);
var result = await c.compileStringAsync(source,
Expand All @@ -246,7 +265,8 @@ Future<String> compileStringAsync(String source,
style: style,
importer: importer,
url: url,
sourceMap: sourceMap != null);
sourceMap: sourceMap != null,
charset: charset);
if (sourceMap != null) sourceMap(result.sourceMap);
return result.css;
}
18 changes: 12 additions & 6 deletions lib/src/async_compile.dart
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,8 @@ Future<CompileResult> compileAsync(String path,
bool useSpaces = true,
int indentWidth,
LineFeed lineFeed,
bool sourceMap = false}) async {
bool sourceMap = false,
bool charset = true}) async {
// If the syntax is different than the importer would default to, we have to
// parse the file manually and we can't store it in the cache.
Stylesheet stylesheet;
Expand All @@ -62,7 +63,8 @@ Future<CompileResult> compileAsync(String path,
useSpaces,
indentWidth,
lineFeed,
sourceMap);
sourceMap,
charset);
}

/// Like [compileStringAsync] in `lib/sass.dart`, but provides more options to
Expand All @@ -84,7 +86,8 @@ Future<CompileResult> compileStringAsync(String source,
int indentWidth,
LineFeed lineFeed,
url,
bool sourceMap = false}) async {
bool sourceMap = false,
bool charset = true}) async {
var stylesheet =
Stylesheet.parse(source, syntax ?? Syntax.scss, url: url, logger: logger);

Expand All @@ -99,7 +102,8 @@ Future<CompileResult> compileStringAsync(String source,
useSpaces,
indentWidth,
lineFeed,
sourceMap);
sourceMap,
charset);
}

/// Compiles [stylesheet] and returns its result.
Expand All @@ -116,7 +120,8 @@ Future<CompileResult> _compileStylesheet(
bool useSpaces,
int indentWidth,
LineFeed lineFeed,
bool sourceMap) async {
bool sourceMap,
bool charset) async {
var evaluateResult = await evaluateAsync(stylesheet,
importCache: importCache,
nodeImporter: nodeImporter,
Expand All @@ -130,7 +135,8 @@ Future<CompileResult> _compileStylesheet(
useSpaces: useSpaces,
indentWidth: indentWidth,
lineFeed: lineFeed,
sourceMap: sourceMap);
sourceMap: sourceMap,
charset: charset);

if (serializeResult.sourceMap != null && importCache != null) {
// TODO(nweiz): Don't explicitly use a type parameter when dart-lang/sdk#25490
Expand Down
20 changes: 13 additions & 7 deletions lib/src/compile.dart
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
// DO NOT EDIT. This file was generated from async_compile.dart.
// See tool/synchronize.dart for details.
//
// Checksum: 2bb00947655b3add16335253802a82188d730595
// Checksum: ea78ec4431055c1d222e52f4ea54a9659c4df11f
//
// ignore_for_file: unused_import

Expand Down Expand Up @@ -45,7 +45,8 @@ CompileResult compile(String path,
bool useSpaces = true,
int indentWidth,
LineFeed lineFeed,
bool sourceMap = false}) {
bool sourceMap = false,
bool charset = true}) {
// If the syntax is different than the importer would default to, we have to
// parse the file manually and we can't store it in the cache.
Stylesheet stylesheet;
Expand All @@ -71,7 +72,8 @@ CompileResult compile(String path,
useSpaces,
indentWidth,
lineFeed,
sourceMap);
sourceMap,
charset);
}

/// Like [compileString] in `lib/sass.dart`, but provides more options to
Expand All @@ -93,7 +95,8 @@ CompileResult compileString(String source,
int indentWidth,
LineFeed lineFeed,
url,
bool sourceMap = false}) {
bool sourceMap = false,
bool charset = true}) {
var stylesheet =
Stylesheet.parse(source, syntax ?? Syntax.scss, url: url, logger: logger);

Expand All @@ -108,7 +111,8 @@ CompileResult compileString(String source,
useSpaces,
indentWidth,
lineFeed,
sourceMap);
sourceMap,
charset);
}

/// Compiles [stylesheet] and returns its result.
Expand All @@ -125,7 +129,8 @@ CompileResult _compileStylesheet(
bool useSpaces,
int indentWidth,
LineFeed lineFeed,
bool sourceMap) {
bool sourceMap,
bool charset) {
var evaluateResult = evaluate(stylesheet,
importCache: importCache,
nodeImporter: nodeImporter,
Expand All @@ -139,7 +144,8 @@ CompileResult _compileStylesheet(
useSpaces: useSpaces,
indentWidth: indentWidth,
lineFeed: lineFeed,
sourceMap: sourceMap);
sourceMap: sourceMap,
charset: charset);

if (serializeResult.sourceMap != null && importCache != null) {
// TODO(nweiz): Don't explicitly use a type parameter when dart-lang/sdk#25490
Expand Down
12 changes: 8 additions & 4 deletions lib/src/executable/compile_stylesheet.dart
Original file line number Diff line number Diff line change
Expand Up @@ -67,13 +67,15 @@ Future compileStylesheet(ExecutableOptions options, StylesheetGraph graph,
importCache: importCache,
importer: FilesystemImporter('.'),
style: options.style,
sourceMap: options.emitSourceMap)
sourceMap: options.emitSourceMap,
charset: options.charset)
: await compileAsync(source,
syntax: syntax,
logger: options.logger,
importCache: importCache,
style: options.style,
sourceMap: options.emitSourceMap);
sourceMap: options.emitSourceMap,
charset: options.charset);
} else {
result = source == null
? compileString(await readStdin(),
Expand All @@ -82,13 +84,15 @@ Future compileStylesheet(ExecutableOptions options, StylesheetGraph graph,
importCache: graph.importCache,
importer: FilesystemImporter('.'),
style: options.style,
sourceMap: options.emitSourceMap)
sourceMap: options.emitSourceMap,
charset: options.charset)
: compile(source,
syntax: syntax,
logger: options.logger,
importCache: graph.importCache,
style: options.style,
sourceMap: options.emitSourceMap);
sourceMap: options.emitSourceMap,
charset: options.charset);
}

var css = result.css;
Expand Down
7 changes: 7 additions & 0 deletions lib/src/executable/options.dart
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,9 @@ class ExecutableOptions {
help: 'Output style.',
allowed: ['expanded', 'compressed'],
defaultsTo: 'expanded')
..addFlag('charset',
help: 'Emit a @charset or BOM for CSS with non-ASCII characters.',
defaultsTo: true)
..addFlag('update',
help: 'Only compile out-of-date stylesheets.', negatable: false);

Expand Down Expand Up @@ -171,6 +174,10 @@ class ExecutableOptions {
? OutputStyle.compressed
: OutputStyle.expanded;

/// Whether to include a `@charset` declaration or a BOM if the stylesheet
/// contains any non-ASCII characters.
bool get charset => _options['charset'] as bool;

/// The set of paths Sass in which should look for imported files.
List<String> get loadPaths => _options['load-path'] as List<String>;

Expand Down
8 changes: 6 additions & 2 deletions lib/src/visitor/serialize.dart
Original file line number Diff line number Diff line change
Expand Up @@ -39,13 +39,17 @@ import 'interface/value.dart';
///
/// If [sourceMap] is `true`, the returned [SerializeResult] will contain a
/// source map indicating how the original Sass files map to the compiled CSS.
///
/// If [charset] is `true`, this will include a `@charset` declaration or a BOM
/// if the stylesheet contains any non-ASCII characters.
SerializeResult serialize(CssNode node,
{OutputStyle style,
bool inspect = false,
bool useSpaces = true,
int indentWidth,
LineFeed lineFeed,
bool sourceMap = false}) {
bool sourceMap = false,
bool charset = true}) {
indentWidth ??= 2;
var visitor = _SerializeVisitor(
style: style,
Expand All @@ -57,7 +61,7 @@ SerializeResult serialize(CssNode node,
node.accept(visitor);
var css = visitor._buffer.toString();
String prefix;
if (css.codeUnits.any((codeUnit) => codeUnit > 0x7F)) {
if (charset && css.codeUnits.any((codeUnit) => codeUnit > 0x7F)) {
if (style == OutputStyle.compressed) {
prefix = '\uFEFF';
} else {
Expand Down
2 changes: 1 addition & 1 deletion pubspec.yaml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
name: sass
version: 1.17.5-dev
version: 1.18.0
description: A Sass implementation in Dart.
author: Dart Team <[email protected]>
homepage: https://github.com/sass/dart-sass
Expand Down
Loading

0 comments on commit 3b3a43a

Please sign in to comment.