-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathoverlay.js
More file actions
137 lines (110 loc) · 4.06 KB
/
Copy pathoverlay.js
File metadata and controls
137 lines (110 loc) · 4.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
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
// overlay.js — Injects visual highlights + tooltips for flagged elements
window.DPOverlay = (() => {
const SEVERITY_ICON = {
critical: '🚨',
high: '⚠️',
medium: 'ℹ️',
info: '👁',
};
let tooltip = null;
let summaryPill = null;
let activeFindings = [];
function init() {
// Create shared tooltip element
tooltip = document.createElement('div');
tooltip.className = 'dp-tooltip';
tooltip.innerHTML = `
<div class="dp-tooltip-title"></div>
<div class="dp-tooltip-body"></div>
<div class="dp-tooltip-category"></div>
`;
document.body.appendChild(tooltip);
}
function highlightElement(finding) {
const el = finding.element;
if (!el || !document.body.contains(el)) return;
// Make the element position:relative so we can anchor the badge
const existingPosition = window.getComputedStyle(el).position;
if (existingPosition === 'static') {
el.style.position = 'relative';
}
el.classList.add('dp-highlight');
el.setAttribute('data-dp-severity', finding.severity);
el.setAttribute('data-dp-id', finding.patternId);
// Badge
const badge = document.createElement('span');
badge.className = 'dp-badge';
badge.setAttribute('data-severity', finding.severity);
badge.textContent = `${SEVERITY_ICON[finding.severity]} ${finding.label}`;
badge.addEventListener('mouseenter', (e) => showTooltip(e, finding));
badge.addEventListener('mouseleave', hideTooltip);
badge.addEventListener('click', (e) => {
e.stopPropagation();
chrome.runtime.sendMessage({ type: 'OPEN_POPUP' });
});
el.appendChild(badge);
}
function showTooltip(event, finding) {
const titleEl = tooltip.querySelector('.dp-tooltip-title');
const bodyEl = tooltip.querySelector('.dp-tooltip-body');
const catEl = tooltip.querySelector('.dp-tooltip-category');
titleEl.textContent = finding.label;
bodyEl.textContent = finding.explanation;
catEl.textContent = `Category: ${finding.category}`;
tooltip.classList.add('visible');
positionTooltip(event.clientX, event.clientY);
}
function hideTooltip() {
tooltip.classList.remove('visible');
}
function positionTooltip(x, y) {
const tw = tooltip.offsetWidth || 280;
const th = tooltip.offsetHeight || 80;
const vw = window.innerWidth;
const vh = window.innerHeight;
let left = x + 14;
let top = y + 14;
if (left + tw > vw - 10) left = x - tw - 14;
if (top + th > vh - 10) top = y - th - 14;
tooltip.style.left = `${left}px`;
tooltip.style.top = `${top}px`;
}
function renderSummaryPill(findings) {
if (summaryPill) summaryPill.remove();
const criticalCount = findings.filter(f => f.severity === 'critical').length;
const total = findings.length;
summaryPill = document.createElement('div');
summaryPill.id = 'dp-summary-pill';
const countClass = total === 0 ? 'dp-pill-count none' : 'dp-pill-count';
summaryPill.innerHTML = `
<span class="dp-pill-icon">🕵️</span>
<span class="${countClass}">${total}</span>
<span class="dp-pill-label">${total === 0 ? 'No patterns found' : total === 1 ? 'dark pattern' : 'dark patterns'}</span>
`;
summaryPill.title = 'Click to open Dark Pattern Detector';
summaryPill.addEventListener('click', () => {
chrome.runtime.sendMessage({ type: 'OPEN_POPUP' });
});
document.body.appendChild(summaryPill);
}
function clearAll() {
document.querySelectorAll('.dp-highlight').forEach(el => {
el.classList.remove('dp-highlight');
el.removeAttribute('data-dp-severity');
el.removeAttribute('data-dp-id');
el.querySelectorAll('.dp-badge').forEach(b => b.remove());
});
if (summaryPill) { summaryPill.remove(); summaryPill = null; }
activeFindings = [];
}
function render(findings) {
clearAll();
activeFindings = findings;
findings.forEach(highlightElement);
renderSummaryPill(findings);
}
function getFindings() {
return activeFindings;
}
return { init, render, clearAll, getFindings };
})();