Skip to main content

pochoir_extra/
lib.rs

1//! A collection of extra tools to transform components.
2//!
3//! - [CSS enhancer](`EnhancedCss`): used to apply various transforms to `<style>` CSS elements, support scoped CSS, CSS nesting, CSS minification, CSS autoprefixer and polyfiller
4//! - [Accessibility checker](`AccessibilityChecker`) used to check the accessibility of the page in real time in debug mode
5#![doc(html_logo_url = "https://gitlab.com/encre-org/pochoir/raw/main/.assets/logo.png")]
6#![forbid(unsafe_code)]
7#![warn(
8    missing_docs,
9    missing_debug_implementations,
10    trivial_casts,
11    trivial_numeric_casts,
12    unstable_features,
13    unused_import_braces,
14    unused_qualifications,
15    rustdoc::private_doc_tests,
16    rustdoc::broken_intra_doc_links,
17    rustdoc::private_intra_doc_links,
18    clippy::unnecessary_wraps,
19    clippy::too_many_lines,
20    clippy::string_to_string,
21    clippy::explicit_iter_loop,
22    clippy::unnecessary_cast,
23    clippy::missing_errors_doc,
24    clippy::pedantic,
25    clippy::clone_on_ref_ptr,
26    clippy::non_ascii_literal,
27    clippy::dbg_macro,
28    clippy::map_err_ignore,
29    clippy::use_debug,
30    clippy::map_err_ignore,
31    clippy::use_self,
32    clippy::useless_let_if_seq,
33    clippy::verbose_file_reads,
34    clippy::panic,
35    clippy::unimplemented,
36    clippy::todo
37)]
38#![allow(clippy::module_name_repetitions, clippy::must_use_candidate)]
39pub mod accessibility_checker;
40pub mod enhanced_css;
41
42pub use accessibility_checker::AccessibilityChecker;
43pub use enhanced_css::{EnhancedCss, EnhancedCssBundler};
44
45#[cfg(test)]
46mod tests {
47    use std::path::Path;
48
49    use super::*;
50    use enhanced_css::CssBundle;
51    use pochoir::{component_not_found, lang::Context, transformers::Transformers, ComponentFile};
52    use pretty_assertions::assert_eq;
53
54    const FILES: &[(&str, &str, &str)] = &[
55        (
56            "index",
57            "index.html",
58            "
59        <h1>Title of the page</h1>
60        <main>
61            <h3>Section title</h3>
62            <p>Page content</p>
63            <my-component />
64        </main>
65        <style enhanced>
66        main {
67            text-size: 18px;
68            font-weight: extrabold;
69            padding: 1rem 4rem;
70
71            & p {
72                color: green;
73            }
74        }
75        h3 {
76            text-size: 22px;
77        }
78        </style>
79        <style>
80        html, body {
81            width: 100%;
82            height: 100%;
83        }
84        </style>",
85        ),
86        (
87            "my-component",
88            "my-component.html",
89            "
90            <h3>A button</h3>
91            <button>My button</button>
92            <style enhanced>
93            button {
94                background-color: red;
95            }
96            button {
97                border-radius: 12px;
98            }
99            h3 {
100                text-size: 24px;
101            }
102            </style>",
103        ),
104    ];
105
106    #[test]
107    fn enhanced_css() {
108        let mut transformers = Transformers::new().with_transformer(EnhancedCss::new());
109
110        let compiled = pochoir::transform_and_compile(
111            "index",
112            &mut Context::new(),
113            |name| {
114                if let Some((_, file_path, file_content)) = FILES.iter().find(|f| f.0 == name) {
115                    Ok(ComponentFile::new(
116                        Path::new(&file_path).to_owned(),
117                        *file_content,
118                    ))
119                } else {
120                    Err(component_not_found(name))
121                }
122            },
123            &mut transformers,
124        )
125        .unwrap();
126
127        assert_eq!(compiled, "
128        <h1 data-p-fd1ea890>Title of the page</h1>
129        <main data-p-fd1ea890>
130            <h3 data-p-fd1ea890>Section title</h3>
131            <p data-p-fd1ea890>Page content</p>
132            
133            <h3 data-p-3e518db5>A button</h3>
134            <button data-p-3e518db5>My button</button>
135            <style>button:where([data-p-3e518db5]){background-color:red}button:where([data-p-3e518db5]){border-radius:12px}h3:where([data-p-3e518db5]){text-size:24px}</style>
136        </main>
137        
138        <style>
139        html, body {
140            width: 100%;
141            height: 100%;
142        }
143        </style><style>main:where([data-p-fd1ea890]){text-size:18px;font-weight:extrabold;padding:1rem 4rem}main:where([data-p-fd1ea890]) p:where([data-p-fd1ea890]){color:green}h3:where([data-p-fd1ea890]){text-size:22px}</style>".to_string());
144    }
145
146    #[test]
147    fn enhanced_css_bundle() {
148        let mut css_bundle = CssBundle::new();
149        let mut transformers =
150            Transformers::new().with_transformer(EnhancedCssBundler::new(&mut css_bundle));
151
152        let compiled = pochoir::transform_and_compile(
153            "index",
154            &mut Context::new(),
155            |name| {
156                if let Some((_, file_path, file_content)) = FILES.iter().find(|f| f.0 == name) {
157                    Ok(ComponentFile::new(
158                        Path::new(&file_path).to_owned(),
159                        *file_content,
160                    ))
161                } else {
162                    Err(component_not_found(name))
163                }
164            },
165            &mut transformers,
166        )
167        .unwrap();
168
169        drop(transformers);
170        assert_eq!(
171            compiled,
172            "
173        <h1 data-p-fd1ea890>Title of the page</h1>
174        <main data-p-fd1ea890>
175            <h3 data-p-fd1ea890>Section title</h3>
176            <p data-p-fd1ea890>Page content</p>
177            
178            <h3 data-p-3e518db5>A button</h3>
179            <button data-p-3e518db5>My button</button>
180            
181        </main>
182        
183        <style>
184        html, body {
185            width: 100%;
186            height: 100%;
187        }
188        </style>"
189                .to_string()
190        );
191        assert_eq!(css_bundle.finish().unwrap(), "main:where([data-p-fd1ea890]){text-size:18px;font-weight:extrabold;padding:1rem 4rem}main:where([data-p-fd1ea890]) p:where([data-p-fd1ea890]){color:green}h3:where([data-p-fd1ea890]){text-size:22px}button:where([data-p-3e518db5]){background-color:red}button:where([data-p-3e518db5]){border-radius:12px}h3:where([data-p-3e518db5]){text-size:24px}".to_string());
192    }
193}