nova_forms/components/
preview.rs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
use leptos::*;
use leptos_meta::*;

use crate::NovaFormContext;

use super::BaseContext;

pub fn start_preview(form_id: &str) {
    let base_context = expect_context::<BaseContext>();

    js_sys::eval(&format!(r#"
            startPreview("{}", "{}");
        "#,
        form_id,
        base_context.resolve_path("print.css")
    )).ok();
}

pub fn stop_preview(_form_id: &str) {
    js_sys::eval(&format!(r#"
        stopPreview();
    "#)).ok();
}

#[component]
pub fn Preview() -> impl IntoView {
    let nova_form_context = expect_context::<NovaFormContext>();

    view! {
        <Script>r#"
            window.styles = [];

            function resizePreview() {
                const preview = document.getElementById("preview");
                let scaleFactor =  Math.min(1, (preview.parentElement.offsetWidth / preview.scrollWidth));
                if (scaleFactor < 1) {
                    preview.style.position = "absolute";
                    preview.style.width = "210mm";
                    preview.style.transformOrigin = "top left";
                    preview.style.transform = "scale(" + scaleFactor + ")";
                    preview.style.marginRight = -210 * (1 - scaleFactor) + "mm";
                    preview.style.marginBottom = -preview.scrollHeight * (1 - scaleFactor) + "px";
                    preview.parentElement.style.height = preview.scrollHeight * scaleFactor + "px";
                } else {
                    preview.removeAttribute("style");
                    preview.parentElement.removeAttribute("style");
                }
            }

            async function startPreview(formId, printCss) {
                if (document.getElementById("preview-wrapper").classList.contains("visible")) {
                    var preview = document.getElementById("preview");
                    preview.innerHTML = "";
                    var paged = new window.Paged.Previewer();
                    window.previewer = paged;
                    await paged.preview(
                        '<div id="print">' + document.getElementById(formId).innerHTML + '</div>',
                        [printCss],
                        preview
                    );
                    resizePreview();
                }
            }

            async function stopPreview() {
                var preview = document.getElementById("preview");
                preview.removeAttribute("style");
                preview.parentElement.removeAttribute("style");
                window.previewer.removeStyles(preview);
            }

            window.PagedConfig = {
                auto: false
            };

            /*window.addEventListener("DOMContentLoaded", function() {
                const previewObserver = new MutationObserver(function(mutations) {
                    mutations.forEach(function(mutation) {
                        resizePreview();
                    });
                });
                
                previewObserver.observe(document.getElementById("preview"), {
                    childList: true,
                    subtree: true
                });
            });*/
            
            window.addEventListener("resize", resizePreview);
        "#</Script>
        <Script src="https://unpkg.com/pagedjs/dist/paged.polyfill.js"></Script>

        <div id="preview-wrapper" class=move || if nova_form_context.is_preview_mode() { "visible" } else { "hidden" }>
            <div
                id="preview"
            ></div>
        </div>
    }
}