PageSourceSearch

https://r-cons.ru/assets/js/print-article.js

js r-cons.ru collected 2026-10-05 00:01:34 UTC 11,887 bytes, 292 lines download raw bytes

1// Функция для генерации QR-кода через Google Charts API
2function generateQRCode(url, size = 250) {
3    const encodedUrl = encodeURIComponent(url);
4    return `https://chart.googleapis.com/chart?chs=${size}x${size}&cht=qr&chl=${encodedUrl}&choe=UTF-8&chld=H|0`;
5}
6
7// Функция для создания подготовленного контента для печати
8function prepareContentForPrint() {
9    const mainContent = document.querySelector('.page__text');
10    if (!mainContent) {
11        console.error('Основной контент статьи не найден');
12        return null;
13    }
14    
15    // Создаем глубокий клон контента
16    const printContent = mainContent.cloneNode(true);
17    
18    // Удаляем элементы, которые не должны попасть в печать
19    const elementsToRemove = printContent.querySelectorAll(
20        '.no-print, .print-action-btn, .social-share, .comments, form, iframe, script, ' +
21        'nav, .breadcrumbs, .breadcrumb, .share-buttons, header, footer, aside, ' +
22        '.chat-window, .chat-button, .modal, .popup, button, input, textarea, select'
23    );
24    elementsToRemove.forEach(el => el.remove());
25    
26    // Убираем первые списки (5 точек)
27    const firstLists = printContent.querySelectorAll('ul, ol');
28    for (let i = 0; i < Math.min(3, firstLists.length); i++) {
29        const list = firstLists[i];
30        const items = list.querySelectorAll('li');
31        if (items.length <= 6) {
32            list.remove();
33        }
34    }
35    
36    // Обработка подписей - исправляем структуру
37    const authorCards = printContent.querySelectorAll('.BQ-author-card');
38    authorCards.forEach(card => {
39        // Убедимся, что фото и контент в правильном порядке
40        const avatar = card.querySelector('.BQ-author-card__avatar');
41        const content = card.querySelector('.BQ-author-card__content');
42        
43        if (avatar && content) {
44            // Перемещаем фото в начало (слева)
45            card.prepend(avatar);
46            
47            // Уменьшаем фото
48            const img = avatar.querySelector('img');
49            if (img) {
50                img.style.width = '15mm';
51                img.style.height = '15mm';
52                img.style.borderRadius = '50%';
53                img.style.border = '1pt solid #ccc';
54                img.style.objectFit = 'cover';
55            }
56            
57            // Убираем подчеркивание у фио и уменьшаем шрифт
58            const links = content.querySelectorAll('a');
59            links.forEach(link => {
60                link.style.textDecoration = 'none';
61                link.style.color = '#000';
62            });
63            
64            // Добавляем отступ слева как в цитатах
65            card.style.paddingLeft = '10mm';
66        }
67    });
68    
69    // Убираем ненужные изображения в других местах
70    const imagesToRemove = printContent.querySelectorAll(
71        '.BQ-expert-approach img, .expert-approach img, [class*="expert"] img, ' +
72        '[class*="approach"] img, .expert-photo img, .author-photo img, .profile-photo img'
73    );
74    imagesToRemove.forEach(img => img.remove());
75    
76    // Создаем автоматическое содержание, если его нет
77    const hasToc = printContent.querySelector('.toc, .table-of-contents, #toc');
78    if (!hasToc) {
79        const headings = printContent.querySelectorAll('h2');
80        if (headings.length > 0) {
81            const toc = document.createElement('div');
82            toc.className = 'table-of-contents';
83            const list = document.createElement('ol');
84            
85            headings.forEach((heading, index) => {
86                const listItem = document.createElement('li');
87                const link = document.createElement('a');
88                link.href = `#heading-${index}`;
89                link.textContent = heading.textContent;
90                link.style.textDecoration = 'none';
91                link.style.color = '#000';
92                listItem.appendChild(link);
93                list.appendChild(listItem);
94                
95                heading.id = `heading-${index}`;
96            });
97            
98            toc.appendChild(list);
99            const h1 = printContent.querySelector('h1');
100            if (h1) {
101                h1.parentNode.insertBefore(toc, h1.nextSibling);
102            }
103        }
104    }
105    
106    return printContent;
107}
108
109// Основная функция печати через кнопку
110window.printArticle = function() {
111    const printContent = prepareContentForPrint();
112    if (!printContent) {
113        alert('Не удалось подготовить контент для печати');
114        return;
115    }
116    
117    // Генерируем QR-код
118    const currentUrl = window.location.href;
119    const qrCodeUrl = generateQRCode(currentUrl, 200);
120    
121    // Создаем HTML для печати
122    const printHtml = `
123        <!DOCTYPE html>
124        <html>
125        <head>
126            <meta charset="utf-8">
127            <title>${document.title || 'Печать статьи'}</title>
128            <style>
129                body { 
130                    margin: 0; 
131                    padding: 0;
132                    font-family: 'Arial', sans-serif;
133                }
134                @page { 
135                    margin: 2cm 1cm 2.5cm 2cm;
136                }
137                .no-print { display: none !important; }
138            </style>
139            <link rel="stylesheet" href="/assets/styles/print-styles.css">
140        </head>
141        <body>
142            <div class="page__text">
143                ${printContent.innerHTML}
144                <div class="print-qr-code">
145                    <p>Для онлайн-версии статьи отсканируйте QR-код:</p>
146                    <img src="${qrCodeUrl}" alt="QR-код статьи" 
147                         onerror="this.style.display='none'; this.parentNode.querySelector('.print-qr-code p').innerHTML='Онлайн-версия: ${currentUrl}';">
148                    <p>Или перейдите по ссылке:<br>
149                    <small>${currentUrl}</small></p>
150                </div>
151            </div>
152        </body>
153        </html>
154    `;
155    
156    // Открываем новое окно для печати
157    const printWindow = window.open('', '_blank', 'width=800,height=600');
158    
159    if (!printWindow) {
160        alert('Разрешите всплывающие окна для печати статьи');
161        return;
162    }
163    
164    printWindow.document.write(printHtml);
165    printWindow.document.close();
166    
167    // Ждем загрузки стилей и запускаем печать
168    setTimeout(() => {
169        printWindow.focus();
170        printWindow.print();
171        printWindow.onafterprint = () => setTimeout(() => printWindow.close(), 100);
172    }, 500);
173};
174
175// Обработчик Ctrl+P для стандартной печати браузера
176document.addEventListener('keydown', function(e) {
177    if ((e.ctrlKey || e.metaKey) && e.key === 'p') {
178        e.preventDefault();
179        e.stopImmediatePropagation();
180        
181        // Временно скрываем всплывающие окна
182        const popups = document.querySelectorAll('.chat-window, .modal, .popup, [class*="chat"]');
183        const originalStyles = [];
184        
185        popups.forEach(popup => {
186            originalStyles.push({
187                element: popup,
188                display: popup.style.display,
189                className: popup.className
190            });
191            popup.style.display = 'none';
192            popup.classList.add('no-print');
193        });
194        
195        // Добавляем QR-код в конец статьи
196        const mainContent = document.querySelector('.page__text');
197        if (mainContent) {
198            const currentUrl = window.location.href;
199            const qrCodeUrl = generateQRCode(currentUrl, 150);
200            
201            const qrCodeDiv = document.createElement('div');
202            qrCodeDiv.className = 'print-qr-code no-print';
203            qrCodeDiv.innerHTML = `
204                <p>Для онлайн-версии статьи отсканируйте QR-код:</p>
205                <img src="${qrCodeUrl}" alt="QR-код статьи" 
206                     onerror="this.style.display='none';">
207                <p>Или перейдите по ссылке:<br>
208                <small>${currentUrl}</small></p>
209            `;
210            
211            mainContent.appendChild(qrCodeDiv);
212        }
213        
214        // Запускаем стандартную печать
215        setTimeout(() => {
216            window.print();
217            
218            // Восстанавливаем состояние после печати
219            setTimeout(() => {
220                const qrCode = document.querySelector('.print-qr-code.no-print');
221                if (qrCode) {
222                    qrCode.remove();
223                }
224                
225                originalStyles.forEach(style => {
226                    if (style.element) {
227                        style.element.style.display = style.display;
228                        style.element.classList.remove('no-print');
229                    }
230                });
231            }, 100);
232        }, 100);
233        
234        return false;
235    }
236}, true);
237
238// Инициализация при загрузке страницы
239document.addEventListener('DOMContentLoaded', function() {
240    console.log('Система печати инициализирована');
241    
242    // Добавляем кнопку печати, если её нет
243    if (!document.querySelector('.print-action-btn')) {
244        const printBtn = document.createElement('button');
245        printBtn.className = 'print-action-btn';
246        printBtn.onclick = window.printArticle;
247        printBtn.title = 'Распечатать статью';
248        printBtn.innerHTML = '🖨️ Печать';
249        
250        const pageBottom = document.querySelector('.page__bottom');
251        if (pageBottom) {
252            // Вставляем кнопку перед соц. кнопками
253            const socialButtons = pageBottom.querySelector('.social-share, .share-buttons');
254            if (socialButtons) {
255                pageBottom.insertBefore(printBtn, socialButtons);
256            } else {
257                pageBottom.appendChild(printBtn);
258            }
259        }
260    }
261    
262    // Помечаем всплывающие окна как no-print
263    const popups = document.querySelectorAll('.chat-window, .modal, .popup');
264    popups.forEach(popup => {
265        popup.classList.add('no-print');
266    });
267});
268
269
270function generateQRCodeWithLogo(url, size = 250) {
271    // Альтернативные сервисы для генерации QR-кодов
272    const services = [
273        `https://api.qrserver.com/v1/create-qr-code/?size=${size}x${size}&data=${encodeURIComponent(url)}&margin=10`,
274        `https://quickchart.io/qr?text=${encodeURIComponent(url)}&size=${size}&margin=2`,
275        `https://chart.googleapis.com/chart?chs=${size}x${size}&cht=qr&chl=${encodeURIComponent(url)}&choe=UTF-8`
276    ];
277    return services[0]; // Используем первый сервис
278}
279
280
281// В функции printArticle добавить:
282const printDate = new Date().toLocaleDateString('ru-RU', {
283    day: 'numeric',
284    month: 'long',
285    year: 'numeric'
286});
287
288const printFooter = `
289    <div class="print-footer-info">
290        Распечатано: ${printDate} | ${document.title}
291    </div>
292`;

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.