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.