-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathremove-tutor-button.js
More file actions
101 lines (89 loc) · 3.06 KB
/
remove-tutor-button.js
File metadata and controls
101 lines (89 loc) · 3.06 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
// ==UserScript==
// @name Remove "Tutor" button from Edgenuity
// @namespace http://tampermonkey.net/
// @version 1.0.0
// @description The button is annoying, so I removed it.
// @author ButterBoyyo
// @match https://r19.core.learn.edgenuity.com/*
// @icon https://www.google.com/s2/favicons?sz=64&domain=edgenuity.com
// @grant none
// ==/UserScript==
(function () {
'use strict';
const SELECTOR = '.gp-button';
// Fast & simple: inject CSS to hide the button (useful as immediate protection)
const style = document.createElement('style');
style.textContent = `${SELECTOR} { display: none !important; visibility: hidden !important; }`;
document.head?.appendChild(style);
// Remove matching nodes under a given root (Document or ShadowRoot)
function removeElements(root = document) {
try {
const nodes = (root instanceof Document || root instanceof ShadowRoot)
? root.querySelectorAll(SELECTOR)
: [];
nodes.forEach(n => n.remove());
} catch (e) {
// ignore cross-origin shadow/document exceptions
console.error('removeElements error', e);
}
}
// Observe a root (Document or ShadowRoot) for additions and attribute changes
function observeRoot(root) {
try {
const obs = new MutationObserver(mutations => {
// On any relevant mutation, a full sweep is cheap for a single selector
removeElements(root);
});
obs.observe(root instanceof Document ? (root.documentElement || root.body) : root, {
childList: true,
subtree: true,
attributes: true,
attributeFilter: ['class', 'style']
});
// initial pass for this root
removeElements(root);
} catch (e) {
console.error('observeRoot error', e);
}
}
// Hook attachShadow to observe new shadow roots created after this script runs
(function hookAttachShadow() {
try {
const proto = Element.prototype;
if (!proto.__attachShadowHooked) {
const orig = proto.attachShadow;
proto.attachShadow = function (init) {
const sr = orig.call(this, init);
// observe the newly created shadow root
observeRoot(sr);
return sr;
};
proto.__attachShadowHooked = true;
}
} catch (e) {
console.error('attachShadow hook failed', e);
}
})();
// Observe existing shadow roots in the document (if any)
function scanExistingShadowRoots() {
try {
const all = document.querySelectorAll('*');
all.forEach(el => {
if (el.shadowRoot) observeRoot(el.shadowRoot);
});
} catch (e) {
console.error('scanExistingShadowRoots error', e);
}
}
// Main initialization
(function init() {
// immediate removal in the main document
removeElements(document);
// observe the main document
observeRoot(document);
// find & observe any existing shadow roots
scanExistingShadowRoots();
// Optional fallback: periodic sweep (uncomment if needed)
// setInterval(() => removeElements(document), 1500);
})();
})();