-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathcontent.ts
More file actions
121 lines (109 loc) · 3.49 KB
/
content.ts
File metadata and controls
121 lines (109 loc) · 3.49 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
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
import { CONFIG } from '../lib/config'
import type { CommentEvent, CommentSpot } from '../lib/enhancer'
import { logger } from '../lib/logger'
import { EnhancerRegistry, TextareaRegistry } from '../lib/registries'
const enhancers = new EnhancerRegistry()
const enhancedTextareas = new TextareaRegistry()
// Expose for debugging in har:view
;(window as any).gitcassoTextareaRegistry = enhancedTextareas
function sendEventToBackground(type: 'ENHANCED' | 'DESTROYED', spot: CommentSpot): void {
const message: CommentEvent = {
spot,
type,
}
browser.runtime.sendMessage(message).catch((error) => {
logger.debug('Failed to send event to background:', error)
})
}
enhancedTextareas.setEventHandlers(
(spot) => sendEventToBackground('ENHANCED', spot),
(spot) => sendEventToBackground('DESTROYED', spot),
)
export default defineContentScript({
main() {
const textAreasOnPageLoad = document.querySelectorAll<HTMLTextAreaElement>(`textarea`)
for (const textarea of textAreasOnPageLoad) {
enhanceMaybe(textarea)
}
const observer = new MutationObserver(handleMutations)
observer.observe(document.body, {
childList: true,
subtree: true,
})
logger.debug('Extension loaded with', enhancers.getEnhancerCount, 'handlers')
},
matches: ['<all_urls>'],
runAt: 'document_end',
})
function handleMutations(mutations: MutationRecord[]): void {
for (const mutation of mutations) {
for (const node of mutation.addedNodes) {
if (node.nodeType === Node.ELEMENT_NODE) {
const element = node as Element
if (element.tagName === 'TEXTAREA') {
enhanceMaybe(element as HTMLTextAreaElement)
} else {
// Also check for textareas within added subtrees
const textareas = element.querySelectorAll?.('textarea')
if (textareas) {
for (const textarea of textareas) {
enhanceMaybe(textarea)
}
}
}
}
}
for (const node of mutation.removedNodes) {
if (node.nodeType === Node.ELEMENT_NODE) {
const element = node as Element
if (element.tagName === 'TEXTAREA') {
enhancedTextareas.unregisterDueToModification(element as HTMLTextAreaElement)
} else {
// Also check for textareas within removed subtrees
const textareas = element.querySelectorAll?.('textarea')
if (textareas) {
for (const textarea of textareas) {
enhancedTextareas.unregisterDueToModification(textarea)
}
}
}
}
}
}
}
function enhanceMaybe(textarea: HTMLTextAreaElement) {
if (enhancedTextareas.get(textarea)) {
logger.debug('textarea already registered {}', textarea)
return
}
logger.debug('activating textarea {}', textarea)
injectStyles()
try {
const enhancedTextarea = enhancers.tryToEnhance(textarea)
if (enhancedTextarea) {
logger.debug(
'Identified textarea:',
enhancedTextarea.spot.type,
enhancedTextarea.spot.unique_key,
)
enhancedTextareas.register(enhancedTextarea)
} else {
logger.debug('No handler found for textarea')
}
} catch (e) {
logger.error(e)
}
}
const STYLES = `
.${CONFIG.ADDED_OVERTYPE_CLASS} {
background: cyan !important;
}
`
function injectStyles(): void {
if (!document.getElementById('gitcasso-styles')) {
const style = document.createElement('style')
style.textContent = STYLES
style.id = 'gitcasso-styles'
document.head.appendChild(style)
}
}