From e76903cb47d66b23408fdd860d8921facc7a6617 Mon Sep 17 00:00:00 2001 From: ConnorSkees <39542938+ConnorSkees@users.noreply.github.com> Date: Sun, 7 Jun 2020 14:23:15 -0400 Subject: [PATCH] initial implementation of selector-replace --- src/builtin/selector.rs | 23 +++++++++++++++++++++- src/selector/extend/mod.rs | 12 ++++-------- tests/selector-replace.rs | 40 ++++++++++++++++++++++++++++++++++++++ 3 files changed, 66 insertions(+), 9 deletions(-) create mode 100644 tests/selector-replace.rs diff --git a/src/builtin/selector.rs b/src/builtin/selector.rs index 88f327b..a437dbd 100644 --- a/src/builtin/selector.rs +++ b/src/builtin/selector.rs @@ -177,7 +177,28 @@ fn selector_replace( super_selector: &Selector, ) -> SassResult { args.max_args(3)?; - todo!("built-in fn selector-replace") + let selector = arg!(args, scope, super_selector, 0, "selector").to_selector( + args.span(), + scope, + super_selector, + "selector", + false, + )?; + let target = arg!(args, scope, super_selector, 1, "original").to_selector( + args.span(), + scope, + super_selector, + "original", + false, + )?; + let source = arg!(args, scope, super_selector, 2, "replacement").to_selector( + args.span(), + scope, + super_selector, + "replacement", + false, + )?; + Ok(Extender::replace(selector.0, source.0, target.0).to_sass_list()) } fn selector_unify( diff --git a/src/selector/extend/mod.rs b/src/selector/extend/mod.rs index 4fe65d4..70f7e90 100644 --- a/src/selector/extend/mod.rs +++ b/src/selector/extend/mod.rs @@ -189,9 +189,8 @@ impl Extender { if i != 0 { extended = list.components[0..i].to_vec(); } - - extended.extend(result.into_iter()); } + extended.extend(result.into_iter()); } else { if !extended.is_empty() { extended.push(complex); @@ -275,8 +274,6 @@ impl Extender { return None; } - // dbg!(&extended_not_expanded); - let mut first = true; let mut originals: Vec = Vec::new(); @@ -359,7 +356,7 @@ impl Extender { // If `self.mode` isn't `ExtendMode::Normal` and we didn't use all the targets in // `extensions`, extension fails for `compound`. - if targets_used.len() != extensions.len() { + if targets_used.len() > 0 && targets_used.len() != extensions.len() { return None; } @@ -443,7 +440,7 @@ impl Extender { to_unify.push_back(state.extender.components.clone()); } } - if originals.is_empty() { + if !originals.is_empty() { to_unify.push_front(vec![ComplexSelectorComponent::Compound( CompoundSelector { components: originals, @@ -473,8 +470,6 @@ impl Extender { }) .collect(); - dbg!(&unified_paths); - Some( unified_paths .into_iter() @@ -631,6 +626,7 @@ impl Extender { } }) .collect(); + // Older browsers support `:not`, but only with a single complex selector. // In order to support those browsers, we break up the contents of a `:not` // unless it originally contained a selector list. diff --git a/tests/selector-replace.rs b/tests/selector-replace.rs new file mode 100644 index 0000000..853f2bd --- /dev/null +++ b/tests/selector-replace.rs @@ -0,0 +1,40 @@ +#![cfg(test)] + +#[macro_use] +mod macros; + +test!( + simple, + "a {\n color: selector-replace(\"c\", \"c\", \"d\");\n}\n", + "a {\n color: d;\n}\n" +); +test!( + compound, + "a {\n color: selector-replace(\"c.d\", \"c\", \"e\");\n}\n", + "a {\n color: e.d;\n}\n" +); +test!( + complex, + "a {\n color: selector-replace(\"c d\", \"d\", \"e f\");\n}\n", + "a {\n color: c e f, e c f;\n}\n" +); +test!( + psuedo_matches, + "a {\n color: selector-replace(\":matches(c)\", \"c\", \"d\");\n}\n", + "a {\n color: :matches(d);\n}\n" +); +test!( + psuedo_not, + "a {\n color: selector-replace(\":not(c)\", \"c\", \"d\");\n}\n", + "a {\n color: :not(d);\n}\n" +); +test!( + no_op, + "a {\n color: selector-replace(\"c\", \"d\", \"e\");\n}\n", + "a {\n color: c;\n}\n" +); +test!( + partial_no_op, + "a {\n color: selector-replace(\"c, d\", \"d\", \"e\");\n}\n", + "a {\n color: c, e;\n}\n" +);