PageSourceSearch

https://www.techniques-ingenieur.fr/assets/controllers/article_svg_modal_controller-_VdZ6dX.js

js techniques-ingenieur.fr collected 2026-09-24 09:15:40 UTC 4,289 bytes, 116 lines download raw bytes

1import {ApplicationController, useThrottle} from 'stimulus-use'
2import rasterizeHTML from 'rasterizehtml';
3
4/* stimulusFetch: 'lazy' */
5export default class extends ApplicationController {
6    static outlets = ["article-content-remote"]
7    static throttles = ['download']
8    static targets = ['modal', 'export', 'bodyMedias', 'spinner']
9    static values = {
10        contentId: String,
11        mediaBodyUrl:   String
12    }
13
14    connect() {
15        useThrottle(this);
16
17        const modalEl = document.getElementById(`${this.contentIdValue}Modal`)
18        if (modalEl) {
19            modalEl.addEventListener('show.bs.modal', () => {
20                this.loadBody()
21            })
22        }
23    }
24    async loadBody() {
25        if (this._hasLoaded) {
26            return
27        }
28        this._hasLoaded = true
29
30        this.spinnerTarget.classList.remove('d-none')
31
32        const url = this.mediaBodyUrlValue
33        try {
34            const resp = await fetch(url, {
35                headers: { 'X-Requested-With': 'XMLHttpRequest' }
36            })
37            if (!resp.ok) {
38                console.error('Failed to fetch modal content:', resp.statusText)
39                return
40            }
41
42
43            this.bodyMediasTarget.innerHTML = await resp.text()
44        } catch (err) {
45            console.error('Error loading modal body:', err)
46        } finally {
47            this.spinnerTarget.classList.add('d-none')
48        }
49    }
50    async download(event) {
51        if (event.currentTarget.href.length === 0) {
52            const renderTarget = this.articleContentRemoteOutlet.renderTarget;
53            const canvasTarget = this.articleContentRemoteOutlet.canvasTarget;
54            const downloadTarget = event.currentTarget
55            const size = event.params.size;
56
57            await this.loadBody()
58            // Chrome n'ignore pas l'embed lors de l'impression alors que firefox oui
59            let html = this.exportTarget.cloneNode(true)
60            const embed = html.getElementsByTagName('embed')
61
62            // Remove spinner/loading text that can be shown at the top of the downloaded image
63            const spinners = html.querySelectorAll('[data-article-svg-modal-target="spinner"], .spinner-border')
64            spinners.forEach((element) => element.remove())
65
66            const list = Array.prototype.slice.call(embed);
67            list.forEach((element) => element.remove())
68
69            renderTarget.innerHTML = html.innerHTML;
70            const img = renderTarget.querySelector('figure img')
71            const ratio = size / img.width;
72            img.height = img.height * ratio;
73            img.width = img.width * ratio;
74            renderTarget.style.visibility = 'visible';
75
76            canvasTarget.height = renderTarget.offsetHeight;
77            canvasTarget.width = renderTarget.offsetWidth;
78
79            // Remplir le fond en blanc
80            const ctx = canvasTarget.getContext("2d");
81            ctx.fillStyle = "white";
82            ctx.fillRect(0, 0, canvasTarget.width, canvasTarget.height);
83
84            rasterizeHTML.drawHTML(renderTarget.outerHTML, canvasTarget).then(() => {
85                renderTarget.style.visibility = 'hidden';
86
87                downloadTarget.download = this.contentIdValue + '-' + size + '.png';
88                downloadTarget.href = canvasTarget.toDataURL('image/png');
89
90                downloadTarget.click();
91            });
92        }
93    }
94
95    async print() {
96        await this.loadBody()
97        const printTarget = this.articleContentRemoteOutlet.printTarget;
98        const doc = printTarget.contentWindow.document;
99
100        // Chrome n'ignore pas l'embed lors de l'impression alors que firefox oui
101        let html = this.exportTarget.cloneNode(true)
102        const embed = html.getElementsByTagName('embed')
103
104        // Remove spinner/loading text that can be shown at the top of the downloaded image
105        const spinners = html.querySelectorAll('[data-article-svg-modal-target="spinner"], .spinner-border')
106        spinners.forEach((element) => element.remove())
107
108        const list = Array.prototype.slice.call(embed);
109        list.forEach((element) => element.remove())
110
111        doc.write(html.outerHTML);
112        printTarget.focus();
113        printTarget.contentWindow.print();
114        doc.close();
115    }
116}

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.