respect $with
argument to load-css
This commit is contained in:
parent
0254517095
commit
cacf605af8
@ -1,3 +1,5 @@
|
||||
use codemap::Spanned;
|
||||
|
||||
use crate::{
|
||||
args::CallArgs,
|
||||
builtin::{
|
||||
@ -5,7 +7,7 @@ use crate::{
|
||||
call, content_exists, feature_exists, function_exists, get_function,
|
||||
global_variable_exists, inspect, keywords, mixin_exists, type_of, variable_exists,
|
||||
},
|
||||
modules::Module,
|
||||
modules::{Module, ModuleConfig},
|
||||
},
|
||||
error::SassResult,
|
||||
parse::{Parser, Stmt},
|
||||
@ -15,13 +17,15 @@ use crate::{
|
||||
fn load_css(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult<Vec<Stmt>> {
|
||||
args.max_args(2)?;
|
||||
|
||||
let span = args.span();
|
||||
|
||||
// todo: https://github.com/sass/dart-sass/issues/1054
|
||||
let url = match args.get_err(0, "module")? {
|
||||
Value::String(s, ..) => s,
|
||||
v => {
|
||||
return Err((
|
||||
format!("$module: {} is not a string.", v.inspect(args.span())?),
|
||||
args.span(),
|
||||
format!("$module: {} is not a string.", v.inspect(span)?),
|
||||
span,
|
||||
)
|
||||
.into())
|
||||
}
|
||||
@ -30,19 +34,39 @@ fn load_css(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult<Vec<Stmt>
|
||||
let with = match args.default_arg(1, "with", Value::Null)? {
|
||||
Value::Map(map) => Some(map),
|
||||
Value::Null => None,
|
||||
v => {
|
||||
return Err((
|
||||
format!("$with: {} is not a map.", v.inspect(args.span())?),
|
||||
args.span(),
|
||||
)
|
||||
.into())
|
||||
}
|
||||
v => return Err((format!("$with: {} is not a map.", v.inspect(span)?), span).into()),
|
||||
};
|
||||
|
||||
if let Some(..) = with {
|
||||
todo!("`$with` to `load-css` not yet implemented")
|
||||
// todo: tests for `with`
|
||||
if let Some(with) = with {
|
||||
let mut config = ModuleConfig::default();
|
||||
|
||||
for (key, value) in with {
|
||||
let key = match key {
|
||||
Value::String(s, ..) => s,
|
||||
v => {
|
||||
return Err((
|
||||
format!("$with key: {} is not a string.", v.inspect(span)?),
|
||||
span,
|
||||
)
|
||||
.into())
|
||||
}
|
||||
};
|
||||
|
||||
config.insert(
|
||||
Spanned {
|
||||
node: key.into(),
|
||||
span,
|
||||
},
|
||||
value.span(span),
|
||||
)?;
|
||||
}
|
||||
|
||||
let (_, stmts) = parser.load_module(&url, &mut config)?;
|
||||
|
||||
Ok(stmts)
|
||||
} else {
|
||||
parser.parse_single_import(&url, args.span())
|
||||
parser.parse_single_import(&url, span)
|
||||
}
|
||||
}
|
||||
|
||||
|
114
src/parse/mod.rs
114
src/parse/mod.rs
@ -208,6 +208,66 @@ impl<'a> Parser<'a> {
|
||||
Ok(config)
|
||||
}
|
||||
|
||||
pub fn load_module(
|
||||
&mut self,
|
||||
name: &str,
|
||||
config: &mut ModuleConfig,
|
||||
) -> SassResult<(Module, Vec<Stmt>)> {
|
||||
Ok(match name {
|
||||
"sass:color" => (declare_module_color(), Vec::new()),
|
||||
"sass:list" => (declare_module_list(), Vec::new()),
|
||||
"sass:map" => (declare_module_map(), Vec::new()),
|
||||
"sass:math" => (declare_module_math(), Vec::new()),
|
||||
"sass:meta" => (declare_module_meta(), Vec::new()),
|
||||
"sass:selector" => (declare_module_selector(), Vec::new()),
|
||||
"sass:string" => (declare_module_string(), Vec::new()),
|
||||
_ => {
|
||||
if let Some(import) = self.find_import(name.as_ref()) {
|
||||
let mut global_scope = Scope::new();
|
||||
|
||||
let file = self
|
||||
.map
|
||||
.add_file(name.to_owned(), String::from_utf8(fs::read(&import)?)?);
|
||||
|
||||
let stmts = Parser {
|
||||
toks: &mut Lexer::new(&file)
|
||||
.collect::<Vec<Token>>()
|
||||
.into_iter()
|
||||
.peekmore(),
|
||||
map: self.map,
|
||||
path: &import,
|
||||
scopes: self.scopes,
|
||||
global_scope: &mut global_scope,
|
||||
super_selectors: self.super_selectors,
|
||||
span_before: file.span.subspan(0, 0),
|
||||
content: self.content,
|
||||
flags: self.flags,
|
||||
at_root: self.at_root,
|
||||
at_root_has_selector: self.at_root_has_selector,
|
||||
extender: self.extender,
|
||||
content_scopes: self.content_scopes,
|
||||
options: self.options,
|
||||
modules: self.modules,
|
||||
module_config: config,
|
||||
}
|
||||
.parse()?;
|
||||
|
||||
if !config.is_empty() {
|
||||
return Err((
|
||||
"This variable was not declared with !default in the @used module.",
|
||||
self.span_before,
|
||||
)
|
||||
.into());
|
||||
}
|
||||
|
||||
(Module::new_from_scope(global_scope), stmts)
|
||||
} else {
|
||||
return Err(("Can't find stylesheet to import.", self.span_before).into());
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
/// Returns any multiline comments that may have been found
|
||||
/// while loading modules
|
||||
#[allow(clippy::eval_order_dependence)]
|
||||
@ -260,58 +320,10 @@ impl<'a> Parser<'a> {
|
||||
self.whitespace_or_comment();
|
||||
self.expect_char(';')?;
|
||||
|
||||
let module = match module_name.as_ref() {
|
||||
"sass:color" => declare_module_color(),
|
||||
"sass:list" => declare_module_list(),
|
||||
"sass:map" => declare_module_map(),
|
||||
"sass:math" => declare_module_math(),
|
||||
"sass:meta" => declare_module_meta(),
|
||||
"sass:selector" => declare_module_selector(),
|
||||
"sass:string" => declare_module_string(),
|
||||
_ => {
|
||||
if let Some(import) = self.find_import(module_name.as_ref().as_ref()) {
|
||||
let mut global_scope = Scope::new();
|
||||
let (module, mut stmts) =
|
||||
self.load_module(module_name.as_ref(), &mut config)?;
|
||||
|
||||
let file = self.map.add_file(
|
||||
module_name.clone().into_owned(),
|
||||
String::from_utf8(fs::read(&import)?)?,
|
||||
);
|
||||
|
||||
comments.append(
|
||||
&mut Parser {
|
||||
toks: &mut Lexer::new(&file)
|
||||
.collect::<Vec<Token>>()
|
||||
.into_iter()
|
||||
.peekmore(),
|
||||
map: self.map,
|
||||
path: &import,
|
||||
scopes: self.scopes,
|
||||
global_scope: &mut global_scope,
|
||||
super_selectors: self.super_selectors,
|
||||
span_before: file.span.subspan(0, 0),
|
||||
content: self.content,
|
||||
flags: self.flags,
|
||||
at_root: self.at_root,
|
||||
at_root_has_selector: self.at_root_has_selector,
|
||||
extender: self.extender,
|
||||
content_scopes: self.content_scopes,
|
||||
options: self.options,
|
||||
modules: self.modules,
|
||||
module_config: &mut config,
|
||||
}
|
||||
.parse()?,
|
||||
);
|
||||
|
||||
if !config.is_empty() {
|
||||
return Err(("This variable was not declared with !default in the @used module.", span).into());
|
||||
}
|
||||
|
||||
Module::new_from_scope(global_scope)
|
||||
} else {
|
||||
return Err(("Can't find stylesheet to import.", span).into());
|
||||
}
|
||||
}
|
||||
};
|
||||
comments.append(&mut stmts);
|
||||
|
||||
// if the config isn't empty here, that means
|
||||
// variables were passed to a builtin module
|
||||
|
Loading…
x
Reference in New Issue
Block a user