Removes ads, enables text copying, and adds download buttons for question sections
Size
6.0 KB
Version
2.1.2
Created
Oct 28, 2025
Updated
about 1 month ago
1// ==UserScript==
2// @name Examveda Ad Remover & Question Downloader
3// @description Removes ads, enables text copying, and adds download buttons for question sections
4// @version 2.1.2
5// @match https://*.examveda.com/*
6// @icon https://www.examveda.com/favicon.ico
7// @require https://cdnjs.cloudflare.com/ajax/libs/jspdf/2.5.1/jspdf.umd.min.js
8// ==/UserScript==
9// Extension code starts here
10console.log('=== Examveda Extension Starting ===');
11
12// Add CSS to hide ads and enable text selection
13TM_addStyle(`
14 /* Remove all ads */
15 ins.adsbygoogle,
16 .adsbygoogle,
17 [data-ad-slot],
18 [id*="google_ads"],
19 [class*="advertisement"],
20 iframe[src*="doubleclick"],
21 iframe[src*="googlesyndication"] {
22 display: none !important;
23 visibility: hidden !important;
24 height: 0 !important;
25 width: 0 !important;
26 }
27
28 /* Enable text selection everywhere */
29 * {
30 -webkit-user-select: text !important;
31 -moz-user-select: text !important;
32 -ms-user-select: text !important;
33 user-select: text !important;
34 }
35
36 /* Download button styles */
37 .examveda-download-btn {
38 background: #4CAF50 !important;
39 color: white !important;
40 border: none !important;
41 padding: 12px 24px !important;
42 margin: 15px 0 !important;
43 border-radius: 5px !important;
44 cursor: pointer !important;
45 font-size: 16px !important;
46 font-weight: bold !important;
47 box-shadow: 0 2px 5px rgba(0,0,0,0.2) !important;
48 transition: all 0.3s ease !important;
49 display: inline-block !important;
50 }
51
52 .examveda-download-btn:hover {
53 background: #45a049 !important;
54 transform: scale(1.05) !important;
55 }
56`);
57
58console.log('CSS styles added');
59
60// Remove copy protection event listeners
61['copy', 'cut', 'contextmenu', 'selectstart'].forEach(eventType => {
62 document.addEventListener(eventType, function(e) {
63 e.stopPropagation();
64 }, true);
65});
66
67// Override copy protection properties
68document.oncopy = null;
69document.oncut = null;
70document.onselectstart = null;
71document.oncontextmenu = null;
72
73TM_runBody(() => {
74 document.body.oncopy = null;
75 document.body.oncut = null;
76 document.body.onselectstart = null;
77 document.body.oncontextmenu = null;
78 console.log('Copy protection removed');
79});
80
81// Function to physically remove ad elements
82function removeAdElements() {
83 const adSelectors = [
84 'ins.adsbygoogle',
85 '.adsbygoogle',
86 '[data-ad-slot]',
87 '[id*="google_ads"]',
88 'iframe[src*="doubleclick"]',
89 'iframe[src*="googlesyndication"]'
90 ];
91
92 let removedCount = 0;
93 adSelectors.forEach(selector => {
94 const elements = document.querySelectorAll(selector);
95 elements.forEach(el => {
96 el.remove();
97 removedCount++;
98 });
99 });
100
101 if (removedCount > 0) {
102 console.log(`Removed ${removedCount} ad elements`);
103 }
104}
105
106// Function to download section content
107function downloadSection(section, sectionTitle) {
108 console.log('Downloading section:', sectionTitle);
109
110 // Get all text content
111 const content = section.innerText || section.textContent;
112
113 // Create blob and download
114 const blob = new Blob([content], { type: 'text/plain;charset=utf-8' });
115 const url = URL.createObjectURL(blob);
116
117 const a = document.createElement('a');
118 a.href = url;
119 a.download = `${sectionTitle.replace(/[^a-z0-9]/gi, '_')}.txt`;
120 document.body.appendChild(a);
121 a.click();
122 document.body.removeChild(a);
123 URL.revokeObjectURL(url);
124
125 console.log('Download complete:', sectionTitle);
126}
127
128// Function to add download buttons
129function addDownloadButtons() {
130 console.log('Adding download buttons...');
131
132 // Find all question sections
133 const sections = document.querySelectorAll('.page-content.page-shortcode');
134 console.log(`Found ${sections.length} sections`);
135
136 sections.forEach((section, index) => {
137 // Skip if button already exists
138 if (section.querySelector('.examveda-download-btn')) {
139 return;
140 }
141
142 // Get section title
143 const titleElement = section.querySelector('.boxedtitle.page-title h2');
144 const sectionTitle = titleElement ? titleElement.textContent.trim() : `Section_${index + 1}`;
145
146 // Create download button
147 const downloadBtn = document.createElement('button');
148 downloadBtn.className = 'examveda-download-btn';
149 downloadBtn.textContent = '📥 Download This Section';
150 downloadBtn.type = 'button';
151
152 // Add click handler
153 downloadBtn.onclick = function(e) {
154 e.preventDefault();
155 e.stopPropagation();
156 downloadSection(section, sectionTitle);
157 };
158
159 // Insert button after title
160 const titleBox = section.querySelector('.boxedtitle.page-title');
161 if (titleBox) {
162 titleBox.insertAdjacentElement('afterend', downloadBtn);
163 console.log(`Download button added for: ${sectionTitle}`);
164 } else {
165 section.insertBefore(downloadBtn, section.firstChild);
166 console.log(`Download button added at top of section ${index + 1}`);
167 }
168 });
169}
170
171// Main initialization function
172function init() {
173 console.log('Initializing extension...');
174
175 // Remove ads immediately
176 removeAdElements();
177
178 // Add download buttons
179 addDownloadButtons();
180
181 // Set up observer for dynamic content
182 const observer = new MutationObserver(function(mutations) {
183 removeAdElements();
184 addDownloadButtons();
185 });
186
187 observer.observe(document.body, {
188 childList: true,
189 subtree: true
190 });
191
192 // Periodically remove ads
193 setInterval(removeAdElements, 2000);
194
195 console.log('Extension initialized successfully!');
196}
197
198// Wait for page to load
199if (document.readyState === 'loading') {
200 document.addEventListener('DOMContentLoaded', init);
201} else {
202 init();
203}