@prospective.co/procss 0.1.8

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.
Files changed (41) hide show
  1. package/LICENSE +201 -0
  2. package/README.md +45 -0
  3. package/package.json +31 -0
  4. package/src/ast/flat_ruleset.rs +52 -0
  5. package/src/ast/ruleset/mod.rs +229 -0
  6. package/src/ast/ruleset/rule.rs +114 -0
  7. package/src/ast/selector/attribute.rs +90 -0
  8. package/src/ast/selector/combinator.rs +58 -0
  9. package/src/ast/selector/mod.rs +115 -0
  10. package/src/ast/selector/selector_path.rs +230 -0
  11. package/src/ast/selector/selector_term.rs +325 -0
  12. package/src/ast/token/mod.rs +18 -0
  13. package/src/ast/token/space.rs +157 -0
  14. package/src/ast/token/string.rs +59 -0
  15. package/src/ast/token/symbol.rs +32 -0
  16. package/src/ast/tree_ruleset.rs +252 -0
  17. package/src/ast.rs +216 -0
  18. package/src/builder.rs +189 -0
  19. package/src/js_builder.rs +59 -0
  20. package/src/lib.rs +151 -0
  21. package/src/main.rs +40 -0
  22. package/src/parser.rs +36 -0
  23. package/src/render.rs +84 -0
  24. package/src/transform.rs +14 -0
  25. package/src/transformers/apply_import.rs +53 -0
  26. package/src/transformers/apply_mixin.rs +73 -0
  27. package/src/transformers/apply_var.rs +41 -0
  28. package/src/transformers/dedupe.rs +35 -0
  29. package/src/transformers/filter_refs.rs +27 -0
  30. package/src/transformers/flat_self.rs +30 -0
  31. package/src/transformers/inline_url.rs +52 -0
  32. package/src/transformers/mod.rs +43 -0
  33. package/src/utils.rs +90 -0
  34. package/target/cjs/procss.d.ts +22 -0
  35. package/target/cjs/procss.js +217 -0
  36. package/target/cjs/procss_bg.wasm +0 -0
  37. package/target/cjs/procss_bg.wasm.d.ts +12 -0
  38. package/target/esm/procss.d.ts +58 -0
  39. package/target/esm/procss.js +283 -0
  40. package/target/esm/procss_bg.wasm +0 -0
  41. package/target/esm/procss_bg.wasm.d.ts +12 -0
@@ -0,0 +1,52 @@
1
+ // ┌───────────────────────────────────────────────────────────────────────────┐
2
+ // │ │
3
+ // │ ██████╗ ██████╗ ██████╗ Copyright (C) 2022, The Prospective Company │
4
+ // │ ██╔══██╗██╔══██╗██╔═══██╗ │
5
+ // │ ██████╔╝██████╔╝██║ ██║ This file is part of the Procss library, │
6
+ // │ ██╔═══╝ ██╔══██╗██║ ██║ distributed under the terms of the │
7
+ // │ ██║ ██║ ██║╚██████╔╝ Apache License 2.0. The full license can │
8
+ // │ ╚═╝ ╚═╝ ╚═╝ ╚═════╝ be found in the LICENSE file. │
9
+ // │ │
10
+ // └───────────────────────────────────────────────────────────────────────────┘
11
+
12
+ use std::borrow::Cow;
13
+ use std::path::Path;
14
+
15
+ use nom::branch::alt;
16
+ use nom::bytes::complete::{is_not, tag};
17
+ use nom::sequence::delimited;
18
+
19
+ use crate::ast::{Css, Rule};
20
+ use crate::utils::fs;
21
+ #[cfg(feature = "iotest")]
22
+ use crate::utils::IoTestFs;
23
+
24
+ fn parse_url(input: &str) -> nom::IResult<&str, &str> {
25
+ let unquoted = delimited(tag("url("), is_not(")"), tag(")"));
26
+ let quoted = delimited(tag("url(\""), is_not("\""), tag("\")"));
27
+ alt((quoted, unquoted))(input)
28
+ }
29
+
30
+ fn into_data_uri<'a>(path: &Path) -> Cow<'a, str> {
31
+ let contents = fs::read_to_string(path).expect("Error reading file");
32
+ let encoded = base64::encode(contents);
33
+ format!("url(data:image/svg+xml;base64,{})", encoded).into()
34
+ }
35
+
36
+ fn inline_url_impl<'a>(newpath: &str, flat: &mut Css<'a>) {
37
+ flat.transform::<Rule<'a>>(|rule| {
38
+ let path = parse_url(&rule.value)
39
+ .ok()
40
+ .and_then(|x| x.0.is_empty().then_some(Path::new(newpath).join(x.1)));
41
+
42
+ if let Some(path) = &path {
43
+ rule.value = into_data_uri(path);
44
+ }
45
+ })
46
+ }
47
+
48
+ /// Inline `url()` rule properties containing local paths to be replace with the
49
+ /// base64 encoded contents of their respective files.
50
+ pub fn inline_url<'a: 'b, 'b>(newpath: &'b str) -> impl Fn(&mut Css<'a>) + 'b {
51
+ |flat| inline_url_impl(newpath, flat)
52
+ }
@@ -0,0 +1,43 @@
1
+ // ┌───────────────────────────────────────────────────────────────────────────┐
2
+ // │ │
3
+ // │ ██████╗ ██████╗ ██████╗ Copyright (C) 2022, The Prospective Company │
4
+ // │ ██╔══██╗██╔══██╗██╔═══██╗ │
5
+ // │ ██████╔╝██████╔╝██║ ██║ This file is part of the Procss library, │
6
+ // │ ██╔═══╝ ██╔══██╗██║ ██║ distributed under the terms of the │
7
+ // │ ██║ ██║ ██║╚██████╔╝ Apache License 2.0. The full license can │
8
+ // │ ╚═╝ ╚═╝ ╚═╝ ╚═════╝ be found in the LICENSE file. │
9
+ // │ │
10
+ // └───────────────────────────────────────────────────────────────────────────┘
11
+
12
+ //! A collection of transformer functions, utilizing the
13
+ //! [`crate::ast::Css::transform`] and [`crate::ast::Tree::transform`] methods
14
+ //! to apply various useful transformations on their respective structs. The
15
+ //! exports from [`crate::transformers`] are functions which take a `&mut` to
16
+ //! either [`crate::ast::Css`] or [`crate::ast::Tree`].
17
+ //!
18
+ //! # Example
19
+ //!
20
+ //! ```rust
21
+ //! use procss::transformers::apply_mixin;
22
+ //! use procss::{parse, RenderCss};
23
+ //!
24
+ //! let mut tree = parse("div{color:red}").unwrap();
25
+ //! apply_mixin(&mut tree);
26
+ //! let css = tree.flatten_tree().as_css_string();
27
+ //! ```
28
+
29
+ mod apply_import;
30
+ mod apply_mixin;
31
+ mod apply_var;
32
+ mod dedupe;
33
+ mod filter_refs;
34
+ mod flat_self;
35
+ mod inline_url;
36
+
37
+ pub use self::apply_import::apply_import;
38
+ pub use self::apply_mixin::apply_mixin;
39
+ pub use self::apply_var::apply_var;
40
+ pub use self::dedupe::dedupe;
41
+ pub use self::filter_refs::filter_refs;
42
+ pub(crate) use self::flat_self::flat_self;
43
+ pub use self::inline_url::inline_url;
package/src/utils.rs ADDED
@@ -0,0 +1,90 @@
1
+ // ┌───────────────────────────────────────────────────────────────────────────┐
2
+ // │ │
3
+ // │ ██████╗ ██████╗ ██████╗ Copyright (C) 2022, The Prospective Company │
4
+ // │ ██╔══██╗██╔══██╗██╔═══██╗ │
5
+ // │ ██████╔╝██████╔╝██║ ██║ This file is part of the Procss library, │
6
+ // │ ██╔═══╝ ██╔══██╗██║ ██║ distributed under the terms of the │
7
+ // │ ██║ ██║ ██║╚██████╔╝ Apache License 2.0. The full license can │
8
+ // │ ╚═╝ ╚═╝ ╚═╝ ╚═════╝ be found in the LICENSE file. │
9
+ // │ │
10
+ // └───────────────────────────────────────────────────────────────────────────┘
11
+
12
+ use std::path::PathBuf;
13
+
14
+ use crate::render::RenderCss;
15
+
16
+ /// A wrapper around [`Vec`] which guarantees at least `N` elements.
17
+ #[derive(Clone, Debug, Eq, PartialEq, Hash)]
18
+ pub struct MinVec<T, const N: usize>([T; N], Vec<T>);
19
+
20
+ impl<T, const N: usize> MinVec<T, N>
21
+ where
22
+ T: std::fmt::Debug,
23
+ {
24
+ /// Create a new N-element-guaranteed collection.
25
+ pub fn new(head: [T; N], tail: Vec<T>) -> Self {
26
+ MinVec(head, tail)
27
+ }
28
+
29
+ /// Iterate over the values in this collection.
30
+ pub fn iter(&self) -> impl Iterator<Item = &'_ T> {
31
+ self.0.iter().chain(self.1.iter())
32
+ }
33
+
34
+ /// Iterate over the values in this collection.
35
+ pub fn iter_mut(&mut self) -> impl Iterator<Item = &'_ mut T> {
36
+ self.0.iter_mut().chain(self.1.iter_mut())
37
+ }
38
+ }
39
+
40
+ impl<T: RenderCss, const N: usize> RenderCss for MinVec<T, N> {
41
+ fn render(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
42
+ for x in self.0.iter() {
43
+ x.render(f)?;
44
+ }
45
+
46
+ for x in self.1.iter() {
47
+ write!(f, ",")?;
48
+ x.render(f)?;
49
+ }
50
+
51
+ Ok(())
52
+ }
53
+ }
54
+
55
+ /// Givens a root path `outdir` and a relative path `path`, remove the extension
56
+ /// to the latter and join with the former. If the latter path is not relative,
57
+ /// return the former. Useful for moving directory trees while retaining their
58
+ /// relative structure to some root.
59
+ pub fn join_paths(outdir: &str, path: &str) -> PathBuf {
60
+ if let Some(parent) = PathBuf::from(path).parent() {
61
+ PathBuf::from(outdir).join(parent)
62
+ } else {
63
+ PathBuf::from(outdir)
64
+ }
65
+ }
66
+
67
+ #[cfg(feature = "iotest")]
68
+ mod mock {
69
+ #[mockall::automock]
70
+ pub trait IoTestFs {
71
+ fn read_to_string(path: &std::path::Path) -> std::io::Result<String>;
72
+ // where
73
+ // P: AsRef<std::path::Path> + 'static;
74
+
75
+ fn create_dir_all<P>(path: P) -> std::io::Result<()>
76
+ where
77
+ P: AsRef<std::path::Path> + 'static;
78
+
79
+ fn write<P, C>(path: P, content: C) -> std::io::Result<()>
80
+ where
81
+ P: AsRef<std::path::Path> + 'static,
82
+ C: AsRef<[u8]> + 'static;
83
+ }
84
+ }
85
+
86
+ #[cfg(not(feature = "iotest"))]
87
+ pub use std::fs;
88
+
89
+ #[cfg(feature = "iotest")]
90
+ pub use mock::{IoTestFs, MockIoTestFs as fs};
@@ -0,0 +1,22 @@
1
+ /* tslint:disable */
2
+ /* eslint-disable */
3
+ /**
4
+ * An implementation of `BuildCss` which owns its data, suitable for use as an
5
+ * exported type in JavaScript.
6
+ */
7
+ export class BuildCss {
8
+ free(): void;
9
+ /**
10
+ * @param {string} rootdir
11
+ */
12
+ constructor(rootdir: string);
13
+ /**
14
+ * @param {string} path
15
+ * @param {string} content
16
+ */
17
+ add(path: string, content: string): void;
18
+ /**
19
+ * @returns {any}
20
+ */
21
+ compile(): any;
22
+ }
@@ -0,0 +1,217 @@
1
+ let imports = {};
2
+ imports['__wbindgen_placeholder__'] = module.exports;
3
+ let wasm;
4
+ const { TextDecoder, TextEncoder } = require(`util`);
5
+
6
+ let cachedTextDecoder = new TextDecoder('utf-8', { ignoreBOM: true, fatal: true });
7
+
8
+ cachedTextDecoder.decode();
9
+
10
+ let cachedUint8Memory0 = new Uint8Array();
11
+
12
+ function getUint8Memory0() {
13
+ if (cachedUint8Memory0.byteLength === 0) {
14
+ cachedUint8Memory0 = new Uint8Array(wasm.memory.buffer);
15
+ }
16
+ return cachedUint8Memory0;
17
+ }
18
+
19
+ function getStringFromWasm0(ptr, len) {
20
+ return cachedTextDecoder.decode(getUint8Memory0().subarray(ptr, ptr + len));
21
+ }
22
+
23
+ const heap = new Array(32).fill(undefined);
24
+
25
+ heap.push(undefined, null, true, false);
26
+
27
+ let heap_next = heap.length;
28
+
29
+ function addHeapObject(obj) {
30
+ if (heap_next === heap.length) heap.push(heap.length + 1);
31
+ const idx = heap_next;
32
+ heap_next = heap[idx];
33
+
34
+ heap[idx] = obj;
35
+ return idx;
36
+ }
37
+
38
+ function getObject(idx) { return heap[idx]; }
39
+
40
+ function dropObject(idx) {
41
+ if (idx < 36) return;
42
+ heap[idx] = heap_next;
43
+ heap_next = idx;
44
+ }
45
+
46
+ function takeObject(idx) {
47
+ const ret = getObject(idx);
48
+ dropObject(idx);
49
+ return ret;
50
+ }
51
+
52
+ let WASM_VECTOR_LEN = 0;
53
+
54
+ let cachedTextEncoder = new TextEncoder('utf-8');
55
+
56
+ const encodeString = (typeof cachedTextEncoder.encodeInto === 'function'
57
+ ? function (arg, view) {
58
+ return cachedTextEncoder.encodeInto(arg, view);
59
+ }
60
+ : function (arg, view) {
61
+ const buf = cachedTextEncoder.encode(arg);
62
+ view.set(buf);
63
+ return {
64
+ read: arg.length,
65
+ written: buf.length
66
+ };
67
+ });
68
+
69
+ function passStringToWasm0(arg, malloc, realloc) {
70
+
71
+ if (realloc === undefined) {
72
+ const buf = cachedTextEncoder.encode(arg);
73
+ const ptr = malloc(buf.length);
74
+ getUint8Memory0().subarray(ptr, ptr + buf.length).set(buf);
75
+ WASM_VECTOR_LEN = buf.length;
76
+ return ptr;
77
+ }
78
+
79
+ let len = arg.length;
80
+ let ptr = malloc(len);
81
+
82
+ const mem = getUint8Memory0();
83
+
84
+ let offset = 0;
85
+
86
+ for (; offset < len; offset++) {
87
+ const code = arg.charCodeAt(offset);
88
+ if (code > 0x7F) break;
89
+ mem[ptr + offset] = code;
90
+ }
91
+
92
+ if (offset !== len) {
93
+ if (offset !== 0) {
94
+ arg = arg.slice(offset);
95
+ }
96
+ ptr = realloc(ptr, len, len = offset + arg.length * 3);
97
+ const view = getUint8Memory0().subarray(ptr + offset, ptr + len);
98
+ const ret = encodeString(arg, view);
99
+
100
+ offset += ret.written;
101
+ }
102
+
103
+ WASM_VECTOR_LEN = offset;
104
+ return ptr;
105
+ }
106
+
107
+ let cachedInt32Memory0 = new Int32Array();
108
+
109
+ function getInt32Memory0() {
110
+ if (cachedInt32Memory0.byteLength === 0) {
111
+ cachedInt32Memory0 = new Int32Array(wasm.memory.buffer);
112
+ }
113
+ return cachedInt32Memory0;
114
+ }
115
+ /**
116
+ * An implementation of `BuildCss` which owns its data, suitable for use as an
117
+ * exported type in JavaScript.
118
+ */
119
+ class BuildCss {
120
+
121
+ static __wrap(ptr) {
122
+ const obj = Object.create(BuildCss.prototype);
123
+ obj.ptr = ptr;
124
+
125
+ return obj;
126
+ }
127
+
128
+ __destroy_into_raw() {
129
+ const ptr = this.ptr;
130
+ this.ptr = 0;
131
+
132
+ return ptr;
133
+ }
134
+
135
+ free() {
136
+ const ptr = this.__destroy_into_raw();
137
+ wasm.__wbg_buildcss_free(ptr);
138
+ }
139
+ /**
140
+ * @param {string} rootdir
141
+ */
142
+ constructor(rootdir) {
143
+ const ptr0 = passStringToWasm0(rootdir, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
144
+ const len0 = WASM_VECTOR_LEN;
145
+ const ret = wasm.buildcss_new(ptr0, len0);
146
+ return BuildCss.__wrap(ret);
147
+ }
148
+ /**
149
+ * @param {string} path
150
+ * @param {string} content
151
+ */
152
+ add(path, content) {
153
+ const ptr0 = passStringToWasm0(path, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
154
+ const len0 = WASM_VECTOR_LEN;
155
+ const ptr1 = passStringToWasm0(content, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
156
+ const len1 = WASM_VECTOR_LEN;
157
+ wasm.buildcss_add(this.ptr, ptr0, len0, ptr1, len1);
158
+ }
159
+ /**
160
+ * @returns {any}
161
+ */
162
+ compile() {
163
+ try {
164
+ const retptr = wasm.__wbindgen_add_to_stack_pointer(-16);
165
+ wasm.buildcss_compile(retptr, this.ptr);
166
+ var r0 = getInt32Memory0()[retptr / 4 + 0];
167
+ var r1 = getInt32Memory0()[retptr / 4 + 1];
168
+ var r2 = getInt32Memory0()[retptr / 4 + 2];
169
+ if (r2) {
170
+ throw takeObject(r1);
171
+ }
172
+ return takeObject(r0);
173
+ } finally {
174
+ wasm.__wbindgen_add_to_stack_pointer(16);
175
+ }
176
+ }
177
+ }
178
+ module.exports.BuildCss = BuildCss;
179
+
180
+ module.exports.__wbindgen_error_new = function(arg0, arg1) {
181
+ const ret = new Error(getStringFromWasm0(arg0, arg1));
182
+ return addHeapObject(ret);
183
+ };
184
+
185
+ module.exports.__wbg_new_268f7b7dd3430798 = function() {
186
+ const ret = new Map();
187
+ return addHeapObject(ret);
188
+ };
189
+
190
+ module.exports.__wbindgen_string_new = function(arg0, arg1) {
191
+ const ret = getStringFromWasm0(arg0, arg1);
192
+ return addHeapObject(ret);
193
+ };
194
+
195
+ module.exports.__wbg_set_933729cf5b66ac11 = function(arg0, arg1, arg2) {
196
+ const ret = getObject(arg0).set(getObject(arg1), getObject(arg2));
197
+ return addHeapObject(ret);
198
+ };
199
+
200
+ module.exports.__wbindgen_object_drop_ref = function(arg0) {
201
+ takeObject(arg0);
202
+ };
203
+
204
+ module.exports.__wbindgen_throw = function(arg0, arg1) {
205
+ throw new Error(getStringFromWasm0(arg0, arg1));
206
+ };
207
+
208
+ const path = require('path').join(__dirname, 'procss_bg.wasm');
209
+ const bytes = require('fs').readFileSync(path);
210
+
211
+ const wasmModule = new WebAssembly.Module(bytes);
212
+ const wasmInstance = new WebAssembly.Instance(wasmModule, imports);
213
+ wasm = wasmInstance.exports;
214
+ module.exports.__wasm = wasm;
215
+
216
+ wasm.__wbindgen_start();
217
+
Binary file
@@ -0,0 +1,12 @@
1
+ /* tslint:disable */
2
+ /* eslint-disable */
3
+ export const memory: WebAssembly.Memory;
4
+ export function main(a: number, b: number): number;
5
+ export function __wbg_buildcss_free(a: number): void;
6
+ export function buildcss_new(a: number, b: number): number;
7
+ export function buildcss_add(a: number, b: number, c: number, d: number, e: number): void;
8
+ export function buildcss_compile(a: number, b: number): void;
9
+ export function __wbindgen_malloc(a: number): number;
10
+ export function __wbindgen_realloc(a: number, b: number, c: number): number;
11
+ export function __wbindgen_add_to_stack_pointer(a: number): number;
12
+ export function __wbindgen_start(): void;
@@ -0,0 +1,58 @@
1
+ /* tslint:disable */
2
+ /* eslint-disable */
3
+ /**
4
+ * An implementation of `BuildCss` which owns its data, suitable for use as an
5
+ * exported type in JavaScript.
6
+ */
7
+ export class BuildCss {
8
+ free(): void;
9
+ /**
10
+ * @param {string} rootdir
11
+ */
12
+ constructor(rootdir: string);
13
+ /**
14
+ * @param {string} path
15
+ * @param {string} content
16
+ */
17
+ add(path: string, content: string): void;
18
+ /**
19
+ * @returns {any}
20
+ */
21
+ compile(): any;
22
+ }
23
+
24
+ export type InitInput = RequestInfo | URL | Response | BufferSource | WebAssembly.Module;
25
+
26
+ export interface InitOutput {
27
+ readonly memory: WebAssembly.Memory;
28
+ readonly main: (a: number, b: number) => number;
29
+ readonly __wbg_buildcss_free: (a: number) => void;
30
+ readonly buildcss_new: (a: number, b: number) => number;
31
+ readonly buildcss_add: (a: number, b: number, c: number, d: number, e: number) => void;
32
+ readonly buildcss_compile: (a: number, b: number) => void;
33
+ readonly __wbindgen_malloc: (a: number) => number;
34
+ readonly __wbindgen_realloc: (a: number, b: number, c: number) => number;
35
+ readonly __wbindgen_add_to_stack_pointer: (a: number) => number;
36
+ readonly __wbindgen_start: () => void;
37
+ }
38
+
39
+ export type SyncInitInput = BufferSource | WebAssembly.Module;
40
+ /**
41
+ * Instantiates the given `module`, which can either be bytes or
42
+ * a precompiled `WebAssembly.Module`.
43
+ *
44
+ * @param {SyncInitInput} module
45
+ *
46
+ * @returns {InitOutput}
47
+ */
48
+ export function initSync(module: SyncInitInput): InitOutput;
49
+
50
+ /**
51
+ * If `module_or_path` is {RequestInfo} or {URL}, makes a request and
52
+ * for everything else, calls `WebAssembly.instantiate` directly.
53
+ *
54
+ * @param {InitInput | Promise<InitInput>} module_or_path
55
+ *
56
+ * @returns {Promise<InitOutput>}
57
+ */
58
+ export default function init (module_or_path?: InitInput | Promise<InitInput>): Promise<InitOutput>;