Panacea Concept Ad Blocker & PDF Downloader

Blocks all ads, enables text copying, and adds PDF download with A4 formatting

Size

15.7 KB

Version

1.0.1

Created

Nov 18, 2025

Updated

25 days ago

1// ==UserScript==
2// @name		Panacea Concept Ad Blocker & PDF Downloader
3// @description		Blocks all ads, enables text copying, and adds PDF download with A4 formatting
4// @version		1.0.1
5// @match		https://*.panaceaconcept.in/*
6// @grant		GM.getValue
7// @grant		GM.setValue
8// @require		https://cdnjs.cloudflare.com/ajax/libs/jspdf/2.5.1/jspdf.umd.min.js
9// @require		https://cdnjs.cloudflare.com/ajax/libs/html2canvas/1.4.1/html2canvas.min.js
10// ==/UserScript==
11(function() {
12    'use strict';
13
14    console.log('Panacea Concept Ad Blocker & PDF Downloader - Extension loaded');
15
16    // Initialize the extension
17    function init() {
18        blockAllAds();
19        enableTextCopying();
20        addPDFDownloadButton();
21        observeDOMForNewAds();
22        console.log('Extension initialized successfully');
23    }
24
25    // Block all ads on the page
26    function blockAllAds() {
27        console.log('Blocking ads...');
28        
29        // CSS to hide all ad-related elements
30        const adBlockingCSS = `
31            /* Google AdSense */
32            .adsbygoogle,
33            ins.adsbygoogle,
34            .google-auto-placed,
35            #aswift_1_host,
36            #aswift_2_host,
37            [id^="aswift_"],
38            [id^="google_ads_"],
39            .google-anno-skip,
40            .goog-rtopics,
41            
42            /* Common ad containers */
43            .ad, .ads, .advertisement, .banner-ad,
44            [class*="ad-container"],
45            [class*="ad-banner"],
46            [class*="ad-wrapper"],
47            [class*="advertisement"],
48            [id*="ad-container"],
49            [id*="ad-banner"],
50            [id*="advertisement"],
51            
52            /* Floating and popup ads */
53            [class*="floating-ad"],
54            [class*="popup-ad"],
55            [class*="overlay-ad"],
56            [style*="position: fixed"][style*="z-index"],
57            
58            /* Ad scripts and iframes */
59            iframe[src*="doubleclick"],
60            iframe[src*="googlesyndication"],
61            iframe[src*="googleadservices"],
62            iframe[src*="ads"],
63            
64            /* Additional ad patterns */
65            div[id*="google_ads"],
66            div[class*="google-ad"],
67            .sponsored,
68            [data-ad-slot],
69            [data-ad-format] {
70                display: none !important;
71                visibility: hidden !important;
72                opacity: 0 !important;
73                height: 0 !important;
74                width: 0 !important;
75                position: absolute !important;
76                left: -9999px !important;
77            }
78            
79            /* Remove ad spacing */
80            body {
81                margin: 0 !important;
82            }
83        `;
84        
85        TM_addStyle(adBlockingCSS);
86        
87        // Remove ad elements from DOM
88        const adSelectors = [
89            '.adsbygoogle',
90            'ins.adsbygoogle',
91            '.google-auto-placed',
92            '[id^="aswift_"]',
93            '[id^="google_ads_"]',
94            '.google-anno-skip',
95            '.goog-rtopics',
96            'iframe[src*="doubleclick"]',
97            'iframe[src*="googlesyndication"]',
98            'iframe[src*="googleadservices"]',
99            '[data-ad-slot]',
100            '[data-ad-format]'
101        ];
102        
103        adSelectors.forEach(selector => {
104            const elements = document.querySelectorAll(selector);
105            elements.forEach(el => {
106                console.log('Removing ad element:', selector);
107                el.remove();
108            });
109        });
110        
111        console.log('Ads blocked successfully');
112    }
113
114    // Enable text copying on the website
115    function enableTextCopying() {
116        console.log('Enabling text copying...');
117        
118        // CSS to enable text selection
119        const copyEnableCSS = `
120            * {
121                -webkit-user-select: text !important;
122                -moz-user-select: text !important;
123                -ms-user-select: text !important;
124                user-select: text !important;
125            }
126            
127            body {
128                -webkit-touch-callout: default !important;
129            }
130        `;
131        
132        TM_addStyle(copyEnableCSS);
133        
134        // Remove copy protection event listeners
135        const events = ['copy', 'cut', 'paste', 'contextmenu', 'selectstart', 'mousedown', 'mouseup', 'mousemove', 'keydown', 'keypress', 'keyup'];
136        
137        events.forEach(event => {
138            document.addEventListener(event, function(e) {
139                e.stopPropagation();
140            }, true);
141        });
142        
143        // Remove oncopy, oncut, onpaste attributes
144        document.body.oncopy = null;
145        document.body.oncut = null;
146        document.body.onpaste = null;
147        document.body.onselectstart = null;
148        document.body.oncontextmenu = null;
149        
150        console.log('Text copying enabled successfully');
151    }
152
153    // Add PDF download button
154    function addPDFDownloadButton() {
155        console.log('Adding PDF download button...');
156        
157        // Create download button
158        const downloadButton = document.createElement('button');
159        downloadButton.id = 'pdf-download-btn';
160        downloadButton.innerHTML = '📄 Download PDF';
161        downloadButton.title = 'Download page as PDF (A4 format)';
162        
163        // Style the button
164        const buttonCSS = `
165            #pdf-download-btn {
166                position: fixed;
167                bottom: 30px;
168                right: 30px;
169                z-index: 999999;
170                background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
171                color: white;
172                border: none;
173                padding: 15px 25px;
174                font-size: 16px;
175                font-weight: bold;
176                border-radius: 50px;
177                cursor: pointer;
178                box-shadow: 0 4px 15px rgba(0, 0, 0, 0.3);
179                transition: all 0.3s ease;
180                font-family: Arial, sans-serif;
181            }
182            
183            #pdf-download-btn:hover {
184                transform: translateY(-3px);
185                box-shadow: 0 6px 20px rgba(0, 0, 0, 0.4);
186                background: linear-gradient(135deg, #764ba2 0%, #667eea 100%);
187            }
188            
189            #pdf-download-btn:active {
190                transform: translateY(-1px);
191            }
192            
193            #pdf-loading-overlay {
194                position: fixed;
195                top: 0;
196                left: 0;
197                width: 100%;
198                height: 100%;
199                background: rgba(0, 0, 0, 0.8);
200                z-index: 9999999;
201                display: flex;
202                flex-direction: column;
203                justify-content: center;
204                align-items: center;
205                color: white;
206                font-family: Arial, sans-serif;
207            }
208            
209            #pdf-loading-overlay .spinner {
210                border: 5px solid #f3f3f3;
211                border-top: 5px solid #667eea;
212                border-radius: 50%;
213                width: 60px;
214                height: 60px;
215                animation: spin 1s linear infinite;
216                margin-bottom: 20px;
217            }
218            
219            @keyframes spin {
220                0% { transform: rotate(0deg); }
221                100% { transform: rotate(360deg); }
222            }
223            
224            #pdf-loading-overlay .message {
225                font-size: 20px;
226                font-weight: bold;
227                margin-top: 10px;
228            }
229        `;
230        
231        TM_addStyle(buttonCSS);
232        
233        // Add click event to download PDF
234        downloadButton.addEventListener('click', async function() {
235            console.log('PDF download initiated');
236            await generatePDF();
237        });
238        
239        // Add button to page
240        document.body.appendChild(downloadButton);
241        console.log('PDF download button added successfully');
242    }
243
244    // Generate and download PDF
245    async function generatePDF() {
246        try {
247            // Show loading overlay
248            const loadingOverlay = document.createElement('div');
249            loadingOverlay.id = 'pdf-loading-overlay';
250            loadingOverlay.innerHTML = `
251                <div class="spinner"></div>
252                <div class="message">Generating PDF...</div>
253                <div style="font-size: 14px; margin-top: 10px;">Please wait, this may take a moment</div>
254            `;
255            document.body.appendChild(loadingOverlay);
256            
257            console.log('Starting PDF generation...');
258            
259            // Get the main content area
260            const contentArea = document.querySelector('#primary.content-area') || 
261                               document.querySelector('main') || 
262                               document.querySelector('article') || 
263                               document.body;
264            
265            console.log('Content area selected:', contentArea);
266            
267            // Temporarily hide ads and unwanted elements for PDF
268            const elementsToHide = document.querySelectorAll('.adsbygoogle, .google-auto-placed, #pdf-download-btn, header, nav, footer, .sidebar, [class*="ad-"], [id*="ad-"]');
269            elementsToHide.forEach(el => {
270                el.style.display = 'none';
271            });
272            
273            // Create canvas from content
274            const canvas = await html2canvas(contentArea, {
275                scale: 2,
276                useCORS: true,
277                logging: false,
278                backgroundColor: '#ffffff',
279                windowWidth: 1200,
280                windowHeight: document.documentElement.scrollHeight
281            });
282            
283            console.log('Canvas created successfully');
284            
285            // Restore hidden elements
286            elementsToHide.forEach(el => {
287                el.style.display = '';
288            });
289            
290            // A4 dimensions in mm
291            const a4Width = 210;
292            const a4Height = 297;
293            
294            // Create PDF with A4 size
295            const { jsPDF } = window.jspdf;
296            const pdf = new jsPDF({
297                orientation: 'portrait',
298                unit: 'mm',
299                format: 'a4',
300                compress: true
301            });
302            
303            // Calculate dimensions to fit A4
304            const imgWidth = a4Width - 20; // 10mm margin on each side
305            const imgHeight = (canvas.height * imgWidth) / canvas.width;
306            
307            let heightLeft = imgHeight;
308            let position = 10; // Top margin
309            
310            // Add image to PDF
311            const imgData = canvas.toDataURL('image/jpeg', 0.95);
312            
313            // Add first page
314            pdf.addImage(imgData, 'JPEG', 10, position, imgWidth, imgHeight);
315            heightLeft -= (a4Height - 20);
316            
317            // Add additional pages if content is longer than one page
318            while (heightLeft > 0) {
319                position = heightLeft - imgHeight + 10;
320                pdf.addPage();
321                pdf.addImage(imgData, 'JPEG', 10, position, imgWidth, imgHeight);
322                heightLeft -= (a4Height - 20);
323            }
324            
325            // Generate filename from page title
326            const pageTitle = document.title.replace(/[^a-z0-9]/gi, '_').toLowerCase();
327            const filename = `${pageTitle}_${Date.now()}.pdf`;
328            
329            // Save PDF
330            pdf.save(filename);
331            
332            console.log('PDF generated and downloaded successfully:', filename);
333            
334            // Remove loading overlay
335            loadingOverlay.remove();
336            
337            // Show success message
338            showNotification('PDF downloaded successfully!', 'success');
339            
340        } catch (error) {
341            console.error('Error generating PDF:', error);
342            
343            // Remove loading overlay
344            const overlay = document.getElementById('pdf-loading-overlay');
345            if (overlay) overlay.remove();
346            
347            showNotification('Error generating PDF. Please try again.', 'error');
348        }
349    }
350
351    // Show notification
352    function showNotification(message, type) {
353        const notification = document.createElement('div');
354        notification.style.cssText = `
355            position: fixed;
356            top: 20px;
357            right: 20px;
358            z-index: 99999999;
359            background: ${type === 'success' ? '#4CAF50' : '#f44336'};
360            color: white;
361            padding: 15px 25px;
362            border-radius: 5px;
363            font-family: Arial, sans-serif;
364            font-size: 16px;
365            box-shadow: 0 4px 15px rgba(0, 0, 0, 0.3);
366            animation: slideIn 0.3s ease;
367        `;
368        notification.textContent = message;
369        
370        const style = document.createElement('style');
371        style.textContent = `
372            @keyframes slideIn {
373                from {
374                    transform: translateX(400px);
375                    opacity: 0;
376                }
377                to {
378                    transform: translateX(0);
379                    opacity: 1;
380                }
381            }
382        `;
383        document.head.appendChild(style);
384        
385        document.body.appendChild(notification);
386        
387        setTimeout(() => {
388            notification.style.animation = 'slideIn 0.3s ease reverse';
389            setTimeout(() => notification.remove(), 300);
390        }, 3000);
391    }
392
393    // Observe DOM for dynamically loaded ads
394    function observeDOMForNewAds() {
395        console.log('Setting up MutationObserver for dynamic ads...');
396        
397        const observer = new MutationObserver(debounce(function(mutations) {
398            mutations.forEach(function(mutation) {
399                mutation.addedNodes.forEach(function(node) {
400                    if (node.nodeType === 1) { // Element node
401                        // Check if the added node is an ad
402                        if (node.classList && (
403                            node.classList.contains('adsbygoogle') ||
404                            node.classList.contains('google-auto-placed') ||
405                            node.id && (node.id.includes('aswift_') || node.id.includes('google_ads_'))
406                        )) {
407                            console.log('Removing dynamically added ad:', node);
408                            node.remove();
409                        }
410                        
411                        // Check child nodes for ads
412                        const adElements = node.querySelectorAll('.adsbygoogle, .google-auto-placed, [id^="aswift_"], [id^="google_ads_"]');
413                        adElements.forEach(ad => {
414                            console.log('Removing dynamically added ad (child):', ad);
415                            ad.remove();
416                        });
417                    }
418                });
419            });
420        }, 500));
421        
422        observer.observe(document.body, {
423            childList: true,
424            subtree: true
425        });
426        
427        console.log('MutationObserver set up successfully');
428    }
429
430    // Debounce function to limit observer callback frequency
431    function debounce(func, wait) {
432        let timeout;
433        return function executedFunction(...args) {
434            const later = () => {
435                clearTimeout(timeout);
436                func(...args);
437            };
438            clearTimeout(timeout);
439            timeout = setTimeout(later, wait);
440        };
441    }
442
443    // Wait for page to load and initialize
444    if (document.readyState === 'loading') {
445        document.addEventListener('DOMContentLoaded', init);
446    } else {
447        init();
448    }
449
450    // Also run after a short delay to catch late-loading ads
451    setTimeout(() => {
452        blockAllAds();
453        console.log('Secondary ad blocking pass completed');
454    }, 2000);
455
456})();
Panacea Concept Ad Blocker & PDF Downloader | Robomonkey