Removes all ads and banners from Examveda and adds PDF export functionality
Size
11.1 KB
Version
1.0.1
Created
Nov 17, 2025
Updated
21 days ago
1// ==UserScript==
2// @name Examveda Ad-Free with PDF Export
3// @description Removes all ads and banners from Examveda and adds PDF export functionality
4// @version 1.0.1
5// @match https://*.examveda.com/*
6// @icon https://www.examveda.com/favicon.ico
7// @grant GM.getValue
8// @grant GM.setValue
9// ==/UserScript==
10(function() {
11 'use strict';
12
13 console.log('Examveda Ad-Free with PDF Export extension loaded');
14
15 // Function to remove all ads and banners
16 function removeAds() {
17 console.log('Removing ads and banners...');
18
19 // Remove Google AdSense ads
20 const adsenseElements = document.querySelectorAll('ins.adsbygoogle, .adsbygoogle');
21 adsenseElements.forEach(ad => {
22 console.log('Removing AdSense element:', ad);
23 ad.remove();
24 });
25
26 // Remove ad containers
27 const adContainers = document.querySelectorAll('[id*="ad"], [class*="ad-"], [class*="advertisement"], [id*="banner"], [class*="banner"]');
28 adContainers.forEach(container => {
29 // Only remove if it looks like an ad container
30 if (container.querySelector('ins.adsbygoogle') ||
31 container.classList.contains('advertisement') ||
32 container.id.includes('google') ||
33 container.classList.contains('ad-container')) {
34 console.log('Removing ad container:', container);
35 container.remove();
36 }
37 });
38
39 // Remove Google vignette ads
40 const vignettes = document.querySelectorAll('[id*="google_vignette"], [class*="google-vignette"]');
41 vignettes.forEach(vignette => {
42 console.log('Removing vignette:', vignette);
43 vignette.remove();
44 });
45
46 // Remove iframe ads
47 const iframes = document.querySelectorAll('iframe[src*="doubleclick"], iframe[src*="googlesyndication"], iframe[src*="googleadservices"]');
48 iframes.forEach(iframe => {
49 console.log('Removing ad iframe:', iframe);
50 iframe.remove();
51 });
52
53 console.log('Ad removal complete');
54 }
55
56 // Function to add PDF export button
57 function addPDFExportButton() {
58 console.log('Adding PDF export button...');
59
60 // Check if button already exists
61 if (document.getElementById('examveda-pdf-export-btn')) {
62 console.log('PDF export button already exists');
63 return;
64 }
65
66 // Create the PDF export button
67 const pdfButton = document.createElement('button');
68 pdfButton.id = 'examveda-pdf-export-btn';
69 pdfButton.innerHTML = '📄 Export to PDF';
70 pdfButton.style.cssText = `
71 position: fixed;
72 top: 100px;
73 right: 20px;
74 z-index: 9999;
75 background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
76 color: white;
77 border: none;
78 padding: 12px 24px;
79 font-size: 16px;
80 font-weight: bold;
81 border-radius: 8px;
82 cursor: pointer;
83 box-shadow: 0 4px 15px rgba(0, 0, 0, 0.2);
84 transition: all 0.3s ease;
85 `;
86
87 // Add hover effect
88 pdfButton.addEventListener('mouseenter', () => {
89 pdfButton.style.transform = 'translateY(-2px)';
90 pdfButton.style.boxShadow = '0 6px 20px rgba(0, 0, 0, 0.3)';
91 });
92
93 pdfButton.addEventListener('mouseleave', () => {
94 pdfButton.style.transform = 'translateY(0)';
95 pdfButton.style.boxShadow = '0 4px 15px rgba(0, 0, 0, 0.2)';
96 });
97
98 // Add click event to export PDF
99 pdfButton.addEventListener('click', exportToPDF);
100
101 document.body.appendChild(pdfButton);
102 console.log('PDF export button added');
103 }
104
105 // Function to export page to PDF
106 async function exportToPDF() {
107 console.log('Starting PDF export...');
108
109 const button = document.getElementById('examveda-pdf-export-btn');
110 const originalText = button.innerHTML;
111 button.innerHTML = '⏳ Generating PDF...';
112 button.disabled = true;
113
114 try {
115 // Get the main content
116 const mainContent = document.querySelector('.main-content') || document.body;
117
118 // Create a clean copy of the content for PDF
119 const printContent = document.createElement('div');
120 printContent.innerHTML = mainContent.innerHTML;
121
122 // Remove any remaining ads from the print content
123 printContent.querySelectorAll('ins.adsbygoogle, .adsbygoogle, [id*="ad"], [class*="advertisement"]').forEach(el => el.remove());
124
125 // Create a new window for printing
126 const printWindow = window.open('', '_blank');
127
128 // Get page title
129 const pageTitle = document.title || 'Examveda Content';
130
131 // Write the HTML content with A4 styling
132 printWindow.document.write(`
133 <!DOCTYPE html>
134 <html>
135 <head>
136 <title>${pageTitle}</title>
137 <style>
138 @page {
139 size: A4;
140 margin: 2cm;
141 }
142
143 body {
144 font-family: Arial, sans-serif;
145 font-size: 12pt;
146 line-height: 1.6;
147 color: #333;
148 max-width: 21cm;
149 margin: 0 auto;
150 padding: 20px;
151 }
152
153 h1, h2, h3, h4, h5, h6 {
154 color: #2c3e50;
155 margin-top: 1em;
156 margin-bottom: 0.5em;
157 page-break-after: avoid;
158 }
159
160 h1 { font-size: 24pt; }
161 h2 { font-size: 20pt; }
162 h3 { font-size: 16pt; }
163
164 p {
165 margin: 0.5em 0;
166 text-align: justify;
167 }
168
169 .boxedtitle {
170 background: #f8f9fa;
171 padding: 10px;
172 border-left: 4px solid #667eea;
173 margin: 1em 0;
174 }
175
176 .cat-main-div-first {
177 margin: 10px 0;
178 padding: 10px;
179 border: 1px solid #ddd;
180 page-break-inside: avoid;
181 }
182
183 img {
184 max-width: 100%;
185 height: auto;
186 page-break-inside: avoid;
187 }
188
189 table {
190 width: 100%;
191 border-collapse: collapse;
192 margin: 1em 0;
193 page-break-inside: avoid;
194 }
195
196 table, th, td {
197 border: 1px solid #ddd;
198 }
199
200 th, td {
201 padding: 8px;
202 text-align: left;
203 }
204
205 th {
206 background-color: #f8f9fa;
207 }
208
209 .page-break {
210 page-break-before: always;
211 }
212
213 /* Hide navigation and other non-content elements */
214 nav, .header-search, .sidebar, .footer,
215 button, .social-share, .comments {
216 display: none !important;
217 }
218
219 @media print {
220 body {
221 background: white;
222 }
223
224 a {
225 text-decoration: none;
226 color: #333;
227 }
228
229 a[href]:after {
230 content: " (" attr(href) ")";
231 font-size: 0.8em;
232 color: #666;
233 }
234 }
235 </style>
236 </head>
237 <body>
238 <h1>${pageTitle}</h1>
239 <p style="color: #666; font-size: 10pt;">Generated from: ${window.location.href}</p>
240 <hr style="margin: 20px 0; border: none; border-top: 2px solid #667eea;">
241 ${printContent.innerHTML}
242 </body>
243 </html>
244 `);
245
246 printWindow.document.close();
247
248 // Wait for content to load
249 setTimeout(() => {
250 printWindow.focus();
251 printWindow.print();
252
253 // Close the print window after printing
254 setTimeout(() => {
255 printWindow.close();
256 }, 1000);
257
258 button.innerHTML = originalText;
259 button.disabled = false;
260 console.log('PDF export complete');
261 }, 500);
262
263 } catch (error) {
264 console.error('Error exporting to PDF:', error);
265 alert('Failed to export PDF. Please try again.');
266 button.innerHTML = originalText;
267 button.disabled = false;
268 }
269 }
270
271 // Debounce function to prevent excessive calls
272 function debounce(func, wait) {
273 let timeout;
274 return function executedFunction(...args) {
275 const later = () => {
276 clearTimeout(timeout);
277 func(...args);
278 };
279 clearTimeout(timeout);
280 timeout = setTimeout(later, wait);
281 };
282 }
283
284 // Initialize the extension
285 function init() {
286 console.log('Initializing Examveda Ad-Free extension...');
287
288 // Remove ads immediately
289 removeAds();
290
291 // Add PDF export button
292 addPDFExportButton();
293
294 // Watch for dynamically loaded ads
295 const observer = new MutationObserver(debounce(() => {
296 removeAds();
297 }, 1000));
298
299 observer.observe(document.body, {
300 childList: true,
301 subtree: true
302 });
303
304 console.log('Extension initialized successfully');
305 }
306
307 // Wait for DOM to be ready
308 if (document.readyState === 'loading') {
309 document.addEventListener('DOMContentLoaded', init);
310 } else {
311 init();
312 }
313
314})();