@prospective.co/procss 0.1.10 → 0.1.12
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/src/builder.rs +19 -19
- package/src/main.rs +1 -2
- package/src/transformers/apply_import.rs +9 -6
- package/src/transformers/inline_url.rs +11 -4
- package/src/utils.rs +5 -4
- package/target/cjs/procss_bg.wasm +0 -0
- package/target/esm/procss_bg.wasm +0 -0
package/package.json
CHANGED
package/src/builder.rs
CHANGED
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
// └───────────────────────────────────────────────────────────────────────────┘
|
|
11
11
|
|
|
12
12
|
use std::collections::HashMap;
|
|
13
|
-
use std::path::PathBuf;
|
|
13
|
+
use std::path::{Path, PathBuf};
|
|
14
14
|
|
|
15
15
|
use anyhow::Context;
|
|
16
16
|
|
|
@@ -25,15 +25,15 @@ use crate::{ast, transformers, utils};
|
|
|
25
25
|
/// A CSS+ project build, comprising a collection of CSS+ files which may
|
|
26
26
|
/// reference eachother (via `@import`).
|
|
27
27
|
pub struct BuildCss<'a> {
|
|
28
|
-
paths: Vec<
|
|
29
|
-
contents: HashMap<&'a
|
|
30
|
-
trees: HashMap<&'a
|
|
31
|
-
css: HashMap<&'a
|
|
32
|
-
rootdir:
|
|
28
|
+
paths: Vec<PathBuf>,
|
|
29
|
+
contents: HashMap<&'a Path, String>,
|
|
30
|
+
trees: HashMap<&'a Path, ast::Tree<'a>>,
|
|
31
|
+
css: HashMap<&'a Path, ast::Css<'a>>,
|
|
32
|
+
rootdir: PathBuf,
|
|
33
33
|
}
|
|
34
34
|
|
|
35
35
|
/// The compiled output of a [`BuildCss`] collection, obtained from
|
|
36
|
-
/// [`BuildCss::compile`].
|
|
36
|
+
/// [`BuildCss::compile`].
|
|
37
37
|
pub struct CompiledCss<'a>(&'a BuildCss<'a>);
|
|
38
38
|
|
|
39
39
|
/// An incremental build struct for compiling a project's CSS sources.
|
|
@@ -47,7 +47,7 @@ pub struct CompiledCss<'a>(&'a BuildCss<'a>);
|
|
|
47
47
|
/// ```
|
|
48
48
|
impl<'a> BuildCss<'a> {
|
|
49
49
|
/// Create a new [`BuildCss`] rooted at `rootdir`.
|
|
50
|
-
pub fn new<
|
|
50
|
+
pub fn new<P: Into<PathBuf>>(rootdir: P) -> Self {
|
|
51
51
|
Self {
|
|
52
52
|
paths: Default::default(),
|
|
53
53
|
contents: Default::default(),
|
|
@@ -59,17 +59,17 @@ impl<'a> BuildCss<'a> {
|
|
|
59
59
|
|
|
60
60
|
/// Add a file `path` to this build.
|
|
61
61
|
#[cfg(not(target_arch = "wasm32"))]
|
|
62
|
-
pub fn add_file(&mut self, path: &'a
|
|
63
|
-
self.paths.push(path.
|
|
64
|
-
let inpath =
|
|
65
|
-
let txt = fs::read_to_string(inpath
|
|
66
|
-
self.contents.insert(path, txt);
|
|
62
|
+
pub fn add_file<P: ?Sized + AsRef<Path>>(&mut self, path: &'a P) {
|
|
63
|
+
self.paths.push(path.as_ref().into());
|
|
64
|
+
let inpath = self.rootdir.join(path);
|
|
65
|
+
let txt = fs::read_to_string(&inpath).unwrap();
|
|
66
|
+
self.contents.insert(path.as_ref(), txt);
|
|
67
67
|
}
|
|
68
68
|
|
|
69
69
|
/// Add a file `path` to this build.
|
|
70
|
-
pub fn add_content(&mut self, path: &'a
|
|
71
|
-
self.paths.push(path.
|
|
72
|
-
self.contents.insert(path, scss);
|
|
70
|
+
pub fn add_content<P: ?Sized + AsRef<Path>>(&mut self, path: &'a P, scss: String) {
|
|
71
|
+
self.paths.push(path.as_ref().into());
|
|
72
|
+
self.contents.insert(path.as_ref(), scss);
|
|
73
73
|
}
|
|
74
74
|
|
|
75
75
|
/// Compile this [`BuildCss`] start-to-finish, applying all transforms along
|
|
@@ -104,9 +104,9 @@ impl<'a> CompiledCss<'a> {
|
|
|
104
104
|
/// subdirectory structure of the `input` sources passed to
|
|
105
105
|
/// [`BuildCss::add`], relative to `outdir`.
|
|
106
106
|
#[cfg(not(target_arch = "wasm32"))]
|
|
107
|
-
pub fn write(self, outdir:
|
|
107
|
+
pub fn write<P: AsRef<Path>>(self, outdir: P) -> anyhow::Result<()> {
|
|
108
108
|
for (outfile, css, path) in self.iter_files().flatten() {
|
|
109
|
-
let outdir = utils::join_paths(outdir, path);
|
|
109
|
+
let outdir = utils::join_paths(outdir.as_ref(), path);
|
|
110
110
|
fs::create_dir_all(outdir.clone()).unwrap_or_default();
|
|
111
111
|
fs::write(outdir.join(outfile), css)?;
|
|
112
112
|
}
|
|
@@ -126,7 +126,7 @@ impl<'a> CompiledCss<'a> {
|
|
|
126
126
|
Ok(results)
|
|
127
127
|
}
|
|
128
128
|
|
|
129
|
-
fn iter_files(&self) -> impl Iterator<Item = anyhow::Result<(String, String, &'_
|
|
129
|
+
fn iter_files(&self) -> impl Iterator<Item = anyhow::Result<(String, String, &'_ Path)>> {
|
|
130
130
|
self.0.css.iter().map(|(path, css)| {
|
|
131
131
|
let outpath = PathBuf::from(path);
|
|
132
132
|
let outfile = format!(
|
package/src/main.rs
CHANGED
|
@@ -15,14 +15,13 @@ use procss::*;
|
|
|
15
15
|
|
|
16
16
|
#[cfg(not(target_arch = "wasm32"))]
|
|
17
17
|
mod init {
|
|
18
|
-
use std::path::Path;
|
|
19
18
|
use std::{env, fs};
|
|
20
19
|
|
|
21
20
|
use procss::*;
|
|
22
21
|
|
|
23
22
|
pub fn init() -> anyhow::Result<String> {
|
|
24
23
|
let args: Vec<String> = env::args().collect();
|
|
25
|
-
let contents = fs::read_to_string(
|
|
24
|
+
let contents = fs::read_to_string(&args[1]);
|
|
26
25
|
let css = parse(&contents?)?.flatten_tree().as_css_string();
|
|
27
26
|
Ok(css)
|
|
28
27
|
}
|
|
@@ -10,12 +10,13 @@
|
|
|
10
10
|
// └───────────────────────────────────────────────────────────────────────────┘
|
|
11
11
|
|
|
12
12
|
use std::collections::HashMap;
|
|
13
|
+
use std::path::Path;
|
|
13
14
|
|
|
14
15
|
use super::filter_refs;
|
|
15
16
|
use crate::ast::Ruleset::{self};
|
|
16
17
|
use crate::ast::*;
|
|
17
18
|
|
|
18
|
-
pub fn apply_import<'a, 'b>(assets: &'b HashMap<&
|
|
19
|
+
pub fn apply_import<'a, 'b>(assets: &'b HashMap<&Path, Tree<'a>>) -> impl Fn(&mut Tree<'a>) + 'b {
|
|
19
20
|
|tree| {
|
|
20
21
|
tree.transform(|ruleset| {
|
|
21
22
|
let mut replace = None;
|
|
@@ -23,15 +24,17 @@ pub fn apply_import<'a, 'b>(assets: &'b HashMap<&str, Tree<'a>>) -> impl Fn(&mut
|
|
|
23
24
|
if *name == "import" {
|
|
24
25
|
if let Some(val) = val {
|
|
25
26
|
if val.starts_with('\"') {
|
|
26
|
-
replace = assets.get(&val[1..val.len() - 1]).cloned();
|
|
27
|
+
replace = assets.get(Path::new(&val[1..val.len() - 1])).cloned();
|
|
27
28
|
if replace.is_none() {
|
|
28
29
|
panic!("File not found: '{}'", &val[1..val.len() - 1])
|
|
29
30
|
}
|
|
30
31
|
} else if val.starts_with("url(\"ref://") {
|
|
31
|
-
replace = assets.get(&val[11..val.len() - 2]).cloned().map(
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
32
|
+
replace = assets.get(Path::new(&val[11..val.len() - 2])).cloned().map(
|
|
33
|
+
|mut x| {
|
|
34
|
+
filter_refs(&mut x);
|
|
35
|
+
x
|
|
36
|
+
},
|
|
37
|
+
);
|
|
35
38
|
|
|
36
39
|
if replace.is_none() {
|
|
37
40
|
panic!("File not found: '{}'", &val[1..val.len() - 1])
|
|
@@ -27,15 +27,20 @@ fn parse_url(input: &str) -> nom::IResult<&str, &str> {
|
|
|
27
27
|
alt((quoted, unquoted))(input)
|
|
28
28
|
}
|
|
29
29
|
|
|
30
|
-
fn into_data_uri<'a>(path: &Path) -> Cow<'a, str
|
|
31
|
-
|
|
30
|
+
fn into_data_uri<'a>(path: &Path) -> Option<Cow<'a, str>> {
|
|
31
|
+
if path.starts_with("data:") {
|
|
32
|
+
return None;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
let contents = fs::read(path).ok()?;
|
|
32
36
|
let encoded = base64::encode(contents);
|
|
33
37
|
let fff = path.extension().unwrap_or_default().to_string_lossy();
|
|
34
38
|
let fmt = match fff.as_ref() {
|
|
35
39
|
"png" => "png",
|
|
36
40
|
_ => "svg+xml",
|
|
37
41
|
};
|
|
38
|
-
|
|
42
|
+
|
|
43
|
+
Some(format!("url(\"data:image/{};base64,{}\")", fmt, encoded).into())
|
|
39
44
|
}
|
|
40
45
|
|
|
41
46
|
fn inline_url_impl<'a>(newpath: &str, flat: &mut Css<'a>) {
|
|
@@ -46,7 +51,9 @@ fn inline_url_impl<'a>(newpath: &str, flat: &mut Css<'a>) {
|
|
|
46
51
|
|
|
47
52
|
if let Some(path) = &path {
|
|
48
53
|
if path.starts_with(".") || path.starts_with("/") {
|
|
49
|
-
|
|
54
|
+
if let Some(value) = into_data_uri(path) {
|
|
55
|
+
rule.value = value;
|
|
56
|
+
}
|
|
50
57
|
}
|
|
51
58
|
}
|
|
52
59
|
})
|
package/src/utils.rs
CHANGED
|
@@ -9,8 +9,6 @@
|
|
|
9
9
|
// │ │
|
|
10
10
|
// └───────────────────────────────────────────────────────────────────────────┘
|
|
11
11
|
|
|
12
|
-
use std::path::PathBuf;
|
|
13
|
-
|
|
14
12
|
use crate::render::RenderCss;
|
|
15
13
|
|
|
16
14
|
/// A wrapper around [`Vec`] which guarantees at least `N` elements.
|
|
@@ -56,8 +54,8 @@ impl<T: RenderCss, const N: usize> RenderCss for MinVec<T, N> {
|
|
|
56
54
|
/// to the latter and join with the former. If the latter path is not relative,
|
|
57
55
|
/// return the former. Useful for moving directory trees while retaining their
|
|
58
56
|
/// relative structure to some root.
|
|
59
|
-
pub fn join_paths(outdir: &
|
|
60
|
-
if let Some(parent) =
|
|
57
|
+
pub fn join_paths(outdir: &Path, path: &Path) -> PathBuf {
|
|
58
|
+
if let Some(parent) = path.parent() {
|
|
61
59
|
PathBuf::from(outdir).join(parent)
|
|
62
60
|
} else {
|
|
63
61
|
PathBuf::from(outdir)
|
|
@@ -72,6 +70,8 @@ mod mock {
|
|
|
72
70
|
// where
|
|
73
71
|
// P: AsRef<std::path::Path> + 'static;
|
|
74
72
|
|
|
73
|
+
fn read(path: &std::path::Path) -> std::io::Result<Vec<u8>>;
|
|
74
|
+
|
|
75
75
|
fn create_dir_all<P>(path: P) -> std::io::Result<()>
|
|
76
76
|
where
|
|
77
77
|
P: AsRef<std::path::Path> + 'static;
|
|
@@ -85,6 +85,7 @@ mod mock {
|
|
|
85
85
|
|
|
86
86
|
#[cfg(not(feature = "iotest"))]
|
|
87
87
|
pub use std::fs;
|
|
88
|
+
use std::path::{Path, PathBuf};
|
|
88
89
|
|
|
89
90
|
#[cfg(feature = "iotest")]
|
|
90
91
|
pub use mock::{IoTestFs, MockIoTestFs as fs};
|
|
Binary file
|
|
Binary file
|