mirror of
https://github.com/danog/dart-sass.git
synced 2025-01-21 21:31:11 +01:00
Improve callable and value documentation
This documentation now targets external users, since these are part of the public API.
This commit is contained in:
parent
8988c3c7fa
commit
b5a838c9c5
13
CHANGELOG.md
13
CHANGELOG.md
@ -8,6 +8,19 @@
|
||||
* `var()` may now be passed in place of multiple arguments to `rgb()`, `rgba()`,
|
||||
`hsl()` and `hsla()`.
|
||||
|
||||
### Dart API
|
||||
|
||||
* Add a `functions` parameter to `compile()`, `compleString()`,
|
||||
`compileAsync()`, and `compileStringAsync()`. This allows users to define
|
||||
custom functions in Dart that can be invoked from Sass stylesheets.
|
||||
|
||||
* Expose the `Callable` and `AsyncCallable` types, which represent functions
|
||||
that can be invoked from Sass.
|
||||
|
||||
* Expose the `Value` type and its subclasses, as well as the top-level
|
||||
`sassTrue`, `sassFalse`, and `sassNull` values, which represent Sass values
|
||||
that may be passed into or returned from custom functions.
|
||||
|
||||
## 1.0.0-beta.4
|
||||
|
||||
* Support unquoted imports in the indented syntax.
|
||||
|
@ -12,14 +12,80 @@ export 'callable/built_in.dart';
|
||||
export 'callable/plain_css.dart';
|
||||
export 'callable/user_defined.dart';
|
||||
|
||||
/// An interface for objects, such as functions and mixins, that can be invoked
|
||||
/// from Sass by passing in arguments.
|
||||
/// An interface functions and mixins that can be invoked from Sass by passing
|
||||
/// in arguments.
|
||||
///
|
||||
/// This extends [AsyncCallable] because all synchronous callables are also
|
||||
/// usable in asynchronous contexts. [Callable]s are usable with both the
|
||||
/// synchronous and asynchronous `compile()` functions, and as such should be
|
||||
/// used in preference to [AsyncCallable]s if possible.
|
||||
///
|
||||
/// When writing custom functions, it's important to make them as user-friendly
|
||||
/// and as close to the standards set by Sass's core functions as possible. Some
|
||||
/// good guidelines to follow include:
|
||||
///
|
||||
/// * Use `Value.assert*` methods, like [Value.assertString], to cast untyped
|
||||
/// `Value` objects to more specific types. For values from the argument list,
|
||||
/// pass in the argument name as well. This ensures that the user gets good
|
||||
/// error messages when they pass in the wrong type to your function.
|
||||
///
|
||||
/// * Individual classes may have more specific `assert*` methods, like
|
||||
/// [SassNumber.assertInt], which should be used when possible.
|
||||
///
|
||||
/// * In Sass, every value counts as a list. Functions should avoid casting
|
||||
/// values to the `SassList` type, and should use the [Value.asList] method
|
||||
/// instead.
|
||||
///
|
||||
/// * When manipulating values like lists, strings, and numbers that have
|
||||
/// metadata (comma versus sepace separated, bracketed versus unbracketed,
|
||||
/// quoted versus unquoted, units), the output metadata should match the input
|
||||
/// metadata. For lists, the [Value.changeList] method can be used to do this
|
||||
/// automatically.
|
||||
///
|
||||
/// * When in doubt, lists should default to comma-separated, strings should
|
||||
/// default to quoted, and number should default to unitless.
|
||||
abstract class Callable extends AsyncCallable {
|
||||
/// Creates a callable with the given [name] and [arguments] that runs
|
||||
/// [callback] when called.
|
||||
///
|
||||
/// The argument declaration is parsed from [arguments], which uses the same
|
||||
/// syntax as an argument list written in Sass (not including parentheses).
|
||||
/// The [arguments] list may be empty to indicate that the function takes no
|
||||
/// arguments. Arguments may also have default values. Throws a
|
||||
/// [SassFormatException] if parsing fails.
|
||||
///
|
||||
/// Any exceptions thrown by [callback] are automatically converted to Sass
|
||||
/// errors and associated with the function call.
|
||||
///
|
||||
/// For example:
|
||||
///
|
||||
/// ```dart
|
||||
/// new Callable("str-split", r'$string, $divider: " "', (arguments) {
|
||||
/// var string = arguments[0].assertString("string");
|
||||
/// var divider = arguments[1].assertString("divider");
|
||||
/// return new SassList(
|
||||
/// string.value.split(divider.value).map((substring) =>
|
||||
/// new SassString(substring, quotes: string.hasQuotes)),
|
||||
/// ListSeparator.comma);
|
||||
/// });
|
||||
/// ```
|
||||
///
|
||||
/// Callables may also take variable length argument lists. These are declared
|
||||
/// the same way as in Sass, and are passed as the final argument to the
|
||||
/// callback. For example:
|
||||
///
|
||||
/// ```dart
|
||||
/// new Callable("str-join", r'$strings...', (arguments) {
|
||||
/// var args = arguments.first as SassArgumentList;
|
||||
/// var strings = args.map((arg) => arg.assertString()).toList();
|
||||
/// return new SassString(strings.map((string) => string.text).join(),
|
||||
/// quotes: strings.any((string) => string.hasQuotes));
|
||||
/// });
|
||||
/// ```
|
||||
///
|
||||
/// Note that the argument list is always an instance of [SassArgumentList],
|
||||
/// which provides access to keyword arguments using
|
||||
/// [SassArgumentList.keywords].
|
||||
factory Callable(String name, String arguments,
|
||||
Value callback(List<Value> arguments)) = BuiltInCallable;
|
||||
}
|
||||
|
@ -7,16 +7,25 @@ import 'dart:async';
|
||||
import '../value.dart';
|
||||
import 'async_built_in.dart';
|
||||
|
||||
/// An interface for objects, such as functions and mixins, that can be invoked
|
||||
/// from Sass by passing in arguments.
|
||||
/// An interface functions and mixins that can be invoked from Sass by passing
|
||||
/// in arguments.
|
||||
///
|
||||
/// This class represents callables that *need* to do asynchronous work. It's
|
||||
/// only compatible with the asynchonous `compile()` methods. If a callback can
|
||||
/// work synchronously, it should be a [Callable] instead.
|
||||
///
|
||||
/// See [Callable] for more details.
|
||||
abstract class AsyncCallable {
|
||||
/// The callable's name.
|
||||
String get name;
|
||||
|
||||
/// Creates a callable with the given [name] and [arguments] that runs
|
||||
/// [callback] when called.
|
||||
///
|
||||
/// The argument declaration is parsed from [arguments], which should not
|
||||
/// include parentheses. Throws a [SassFormatException] if parsing fails.
|
||||
///
|
||||
/// See [new Callable] for more details.
|
||||
factory AsyncCallable(String name, String arguments,
|
||||
FutureOr<Value> callback(List<Value> arguments)) = AsyncBuiltInCallable;
|
||||
}
|
||||
|
@ -26,7 +26,10 @@ export 'value/string.dart';
|
||||
|
||||
/// A SassScript value.
|
||||
///
|
||||
/// Note that all SassScript values are unmodifiable.
|
||||
/// All SassScript values are unmodifiable. New values can be constructed using
|
||||
/// subclass constructors like [new SassString]. Untyped values can be cast to
|
||||
/// particular types using `assert*()` functions like [assertString], which
|
||||
/// throw user-friendly error messages if they fail.
|
||||
abstract class Value {
|
||||
/// Whether the value will be represented in CSS as the empty string.
|
||||
bool get isBlank => false;
|
||||
@ -70,6 +73,9 @@ abstract class Value {
|
||||
const Value();
|
||||
|
||||
/// Calls the appropriate visit method on [visitor].
|
||||
///
|
||||
/// **Note:** this function should not be called outside the `sass` package.
|
||||
/// It's not guaranteed to be stable across versions.
|
||||
T accept<T>(ValueVisitor<T> visitor);
|
||||
|
||||
/// Throws a [SassScriptException] if [this] isn't a boolean.
|
||||
@ -78,42 +84,42 @@ abstract class Value {
|
||||
/// a literal boolean.
|
||||
///
|
||||
/// If this came from a function argument, [name] is the argument name
|
||||
/// (without the `$`). It's used for debugging.
|
||||
/// (without the `$`). It's used for error reporting.
|
||||
SassBoolean assertBoolean([String name]) =>
|
||||
throw _exception("$this is not a boolean.", name);
|
||||
|
||||
/// Throws a [SassScriptException] if [this] isn't a color.
|
||||
///
|
||||
/// If this came from a function argument, [name] is the argument name
|
||||
/// (without the `$`). It's used for debugging.
|
||||
/// (without the `$`). It's used for error reporting.
|
||||
SassColor assertColor([String name]) =>
|
||||
throw _exception("$this is not a color.", name);
|
||||
|
||||
/// Throws a [SassScriptException] if [this] isn't a function reference.
|
||||
///
|
||||
/// If this came from a function argument, [name] is the argument name
|
||||
/// (without the `$`). It's used for debugging.
|
||||
/// (without the `$`). It's used for error reporting.
|
||||
SassFunction assertFunction([String name]) =>
|
||||
throw _exception("$this is not a function reference.", name);
|
||||
|
||||
/// Throws a [SassScriptException] if [this] isn't a map.
|
||||
///
|
||||
/// If this came from a function argument, [name] is the argument name
|
||||
/// (without the `$`). It's used for debugging.
|
||||
/// (without the `$`). It's used for error reporting.
|
||||
SassMap assertMap([String name]) =>
|
||||
throw _exception("$this is not a map.", name);
|
||||
|
||||
/// Throws a [SassScriptException] if [this] isn't a number.
|
||||
///
|
||||
/// If this came from a function argument, [name] is the argument name
|
||||
/// (without the `$`). It's used for debugging.
|
||||
/// (without the `$`). It's used for error reporting.
|
||||
SassNumber assertNumber([String name]) =>
|
||||
throw _exception("$this is not a number.", name);
|
||||
|
||||
/// Throws a [SassScriptException] if [this] isn't a string.
|
||||
///
|
||||
/// If this came from a function argument, [name] is the argument name
|
||||
/// (without the `$`). It's used for debugging.
|
||||
/// (without the `$`). It's used for error reporting.
|
||||
SassString assertString([String name]) =>
|
||||
throw _exception("$this is not a string.", name);
|
||||
|
||||
@ -125,7 +131,9 @@ abstract class Value {
|
||||
/// [ParentSelector]s. Otherwise, they're considered parse errors.
|
||||
///
|
||||
/// If this came from a function argument, [name] is the argument name
|
||||
/// (without the `$`). It's used for debugging.
|
||||
/// (without the `$`). It's used for error reporting.
|
||||
///
|
||||
/// **Note:** this function should not be called outside the `sass` package.
|
||||
SelectorList assertSelector({String name, bool allowParent: false}) {
|
||||
var string = _selectorString(name);
|
||||
try {
|
||||
@ -145,7 +153,10 @@ abstract class Value {
|
||||
/// [ParentSelector]s. Otherwise, they're considered parse errors.
|
||||
///
|
||||
/// If this came from a function argument, [name] is the argument name
|
||||
/// (without the `$`). It's used for debugging.
|
||||
/// (without the `$`). It's used for error reporting.
|
||||
///
|
||||
/// **Note:** this function should not be called outside the `sass` package.
|
||||
/// It's not guaranteed to be stable across versions.
|
||||
SimpleSelector assertSimpleSelector({String name, bool allowParent: false}) {
|
||||
var string = _selectorString(name);
|
||||
try {
|
||||
@ -165,7 +176,10 @@ abstract class Value {
|
||||
/// [ParentSelector]s. Otherwise, they're considered parse errors.
|
||||
///
|
||||
/// If this came from a function argument, [name] is the argument name
|
||||
/// (without the `$`). It's used for debugging.
|
||||
/// (without the `$`). It's used for error reporting.
|
||||
///
|
||||
/// **Note:** this function should not be called outside the `sass` package.
|
||||
/// It's not guaranteed to be stable across versions.
|
||||
CompoundSelector assertCompoundSelector(
|
||||
{String name, bool allowParent: false}) {
|
||||
var string = _selectorString(name);
|
||||
@ -239,34 +253,58 @@ abstract class Value {
|
||||
}
|
||||
|
||||
/// The SassScript `=` operation.
|
||||
///
|
||||
/// **Note:** this function should not be called outside the `sass` package.
|
||||
/// It's not guaranteed to be stable across versions.
|
||||
Value singleEquals(Value other) =>
|
||||
new SassString("${toCssString()}=${other.toCssString()}");
|
||||
|
||||
/// The SassScript `>` operation.
|
||||
///
|
||||
/// **Note:** this function should not be called outside the `sass` package.
|
||||
/// It's not guaranteed to be stable across versions.
|
||||
SassBoolean greaterThan(Value other) =>
|
||||
throw new SassScriptException('Undefined operation "$this > $other".');
|
||||
|
||||
/// The SassScript `>=` operation.
|
||||
///
|
||||
/// **Note:** this function should not be called outside the `sass` package.
|
||||
/// It's not guaranteed to be stable across versions.
|
||||
SassBoolean greaterThanOrEquals(Value other) =>
|
||||
throw new SassScriptException('Undefined operation "$this >= $other".');
|
||||
|
||||
/// The SassScript `<` operation.
|
||||
///
|
||||
/// **Note:** this function should not be called outside the `sass` package.
|
||||
/// It's not guaranteed to be stable across versions.
|
||||
SassBoolean lessThan(Value other) =>
|
||||
throw new SassScriptException('Undefined operation "$this < $other".');
|
||||
|
||||
/// The SassScript `<=` operation.
|
||||
///
|
||||
/// **Note:** this function should not be called outside the `sass` package.
|
||||
/// It's not guaranteed to be stable across versions.
|
||||
SassBoolean lessThanOrEquals(Value other) =>
|
||||
throw new SassScriptException('Undefined operation "$this <= $other".');
|
||||
|
||||
/// The SassScript `*` operation.
|
||||
///
|
||||
/// **Note:** this function should not be called outside the `sass` package.
|
||||
/// It's not guaranteed to be stable across versions.
|
||||
Value times(Value other) =>
|
||||
throw new SassScriptException('Undefined operation "$this * $other".');
|
||||
|
||||
/// The SassScript `%` operation.
|
||||
///
|
||||
/// **Note:** this function should not be called outside the `sass` package.
|
||||
/// It's not guaranteed to be stable across versions.
|
||||
Value modulo(Value other) =>
|
||||
throw new SassScriptException('Undefined operation "$this % $other".');
|
||||
|
||||
/// The SassScript `+` operation.
|
||||
///
|
||||
/// **Note:** this function should not be called outside the `sass` package.
|
||||
/// It's not guaranteed to be stable across versions.
|
||||
Value plus(Value other) {
|
||||
if (other is SassString) {
|
||||
return new SassString(toCssString() + other.text,
|
||||
@ -277,28 +315,49 @@ abstract class Value {
|
||||
}
|
||||
|
||||
/// The SassScript `-` operation.
|
||||
///
|
||||
/// **Note:** this function should not be called outside the `sass` package.
|
||||
/// It's not guaranteed to be stable across versions.
|
||||
Value minus(Value other) =>
|
||||
new SassString("${toCssString()}-${other.toCssString()}");
|
||||
|
||||
/// The SassScript `/` operation.
|
||||
///
|
||||
/// **Note:** this function should not be called outside the `sass` package.
|
||||
/// It's not guaranteed to be stable across versions.
|
||||
Value dividedBy(Value other) =>
|
||||
new SassString("${toCssString()}/${other.toCssString()}");
|
||||
|
||||
/// The SassScript unary `+` operation.
|
||||
///
|
||||
/// **Note:** this function should not be called outside the `sass` package.
|
||||
/// It's not guaranteed to be stable across versions.
|
||||
Value unaryPlus() => new SassString("+${toCssString()}");
|
||||
|
||||
/// The SassScript unary `-` operation.
|
||||
///
|
||||
/// **Note:** this function should not be called outside the `sass` package.
|
||||
/// It's not guaranteed to be stable across versions.
|
||||
Value unaryMinus() => new SassString("-${toCssString()}");
|
||||
|
||||
/// The SassScript unary `/` operation.
|
||||
///
|
||||
/// **Note:** this function should not be called outside the `sass` package.
|
||||
/// It's not guaranteed to be stable across versions.
|
||||
Value unaryDivide() => new SassString("/${toCssString()}");
|
||||
|
||||
/// The SassScript unary `not` operation.
|
||||
///
|
||||
/// **Note:** this function should not be called outside the `sass` package.
|
||||
/// It's not guaranteed to be stable across versions.
|
||||
Value unaryNot() => sassFalse;
|
||||
|
||||
/// Returns a copy of [this] without [SassNumber.asSlash] set.
|
||||
///
|
||||
/// If this isn't a [SassNumber], returns it as-is.
|
||||
///
|
||||
/// **Note:** this function should not be called outside the `sass` package.
|
||||
/// It's not guaranteed to be stable across versions.
|
||||
Value withoutSlash() => this;
|
||||
|
||||
/// Returns a valid CSS representation of [this].
|
||||
|
@ -9,10 +9,13 @@ import '../value.dart';
|
||||
|
||||
/// A SassScript argument list.
|
||||
///
|
||||
/// An argument list comes from a rest argument, and may contain a keyword map
|
||||
/// as well as the positional arguments.
|
||||
/// An argument list comes from a rest argument. It's distinct from a normal
|
||||
/// [SassList] in that it may contain a keyword map as well as the positional
|
||||
/// arguments.
|
||||
class SassArgumentList extends SassList {
|
||||
/// The keywords attached to this argument list.
|
||||
/// The keyword arguments attached to this argument list.
|
||||
///
|
||||
/// The argument names don't include `$`.
|
||||
Map<String, Value> get keywords {
|
||||
_wereKeywordsAccessed = true;
|
||||
return _keywords;
|
||||
@ -24,6 +27,9 @@ class SassArgumentList extends SassList {
|
||||
///
|
||||
/// This is used to determine whether to throw an exception about passing
|
||||
/// unexpected keywords.
|
||||
///
|
||||
/// **Note:** this function should not be called outside the `sass` package.
|
||||
/// It's not guaranteed to be stable across versions.
|
||||
bool get wereKeywordsAccessed => _wereKeywordsAccessed;
|
||||
var _wereKeywordsAccessed = false;
|
||||
|
||||
|
@ -153,6 +153,11 @@ class SassNumber extends Value {
|
||||
static const precision = 10;
|
||||
|
||||
/// The value of this number.
|
||||
///
|
||||
/// Note that due to details of floating-point arithmetic, this may be a
|
||||
/// [double] even if [this] represents an int from Sass's perspective. Use
|
||||
/// [isInt] to determine whether this is an integer, [asInt] to get its
|
||||
/// integer value, or [assertInt] to do both at once.
|
||||
final num value;
|
||||
|
||||
/// This number's numerator units.
|
||||
@ -165,6 +170,10 @@ class SassNumber extends Value {
|
||||
final String asSlash;
|
||||
|
||||
/// Whether [this] has any units.
|
||||
///
|
||||
/// If a function expects a number to have no units, it should use
|
||||
/// [assertNoUnits]. If it expects the number to have a particular unit, it
|
||||
/// should use [assertUnit].
|
||||
bool get hasUnits => numeratorUnits.isNotEmpty || denominatorUnits.isNotEmpty;
|
||||
|
||||
/// Whether [this] is an integer, according to [fuzzyEquals].
|
||||
@ -224,7 +233,7 @@ class SassNumber extends Value {
|
||||
///
|
||||
/// Throws a [SassScriptException] if [value] isn't an integer. If this came
|
||||
/// from a function argument, [name] is the argument name (without the `$`).
|
||||
/// It's used for debugging.
|
||||
/// It's used for error reporting.
|
||||
int assertInt([String name]) {
|
||||
var integer = fuzzyAsInt(value);
|
||||
if (integer != null) return integer;
|
||||
@ -239,7 +248,7 @@ class SassNumber extends Value {
|
||||
///
|
||||
/// Throws a [SassScriptException] if this isn't an integer or if it isn't a
|
||||
/// valid index for [list]. If this came from a function argument, [name] is
|
||||
/// the argument name (without the `$`). It's used for debugging.
|
||||
/// the argument name (without the `$`). It's used for error reporting.
|
||||
int assertIndexFor(List list, [String name]) {
|
||||
var sassIndex = assertInt(name);
|
||||
if (sassIndex == 0) throw _exception("List index may not be 0.");
|
||||
@ -256,7 +265,7 @@ class SassNumber extends Value {
|
||||
/// If [value] is [fuzzyEquals] to [min] or [max], it's clamped to the
|
||||
/// appropriate value. Otherwise, this throws a [SassScriptException]. If this
|
||||
/// came from a function argument, [name] is the argument name (without the
|
||||
/// `$`). It's used for debugging.
|
||||
/// `$`). It's used for error reporting.
|
||||
num valueInRange(num min, num max, [String name]) {
|
||||
var result = fuzzyCheckRange(value, min, max);
|
||||
if (result != null) return result;
|
||||
@ -274,7 +283,7 @@ class SassNumber extends Value {
|
||||
/// (and as a numerator).
|
||||
///
|
||||
/// If this came from a function argument, [name] is the argument name
|
||||
/// (without the `$`). It's used for debugging.
|
||||
/// (without the `$`). It's used for error reporting.
|
||||
void assertUnit(String unit, [String name]) {
|
||||
if (hasUnit(unit)) return;
|
||||
throw _exception('Expected $this to have unit "$unit".', name);
|
||||
@ -283,7 +292,7 @@ class SassNumber extends Value {
|
||||
/// Throws a [SassScriptException] unless [this] has no units.
|
||||
///
|
||||
/// If this came from a function argument, [name] is the argument name
|
||||
/// (without the `$`). It's used for debugging.
|
||||
/// (without the `$`). It's used for error reporting.
|
||||
void assertNoUnits([String name]) {
|
||||
if (!hasUnits) return;
|
||||
throw _exception('Expected $this to have no units.', name);
|
||||
|
Loading…
x
Reference in New Issue
Block a user