Exclude generic iframe "embed" AOIs from Ranked Attention
Browse filesTRACKING_JS tags every <iframe> identically as "embed" regardless of
size or content — it can't see what's inside one. A single
page-spanning iframe (PDF viewer, embedded system, video player) then
swallowed every gaze sample under one undifferentiated "Embedded
content" bucket, reporting 100% attention on something that isn't a
real, distinguishable target. _find_aoi() now skips "embed" candidates
so those points go unlabeled instead, the same as any other untracked
area — raw gaze data and the per-segment heatmap are unaffected, only
the Ranked Attention/Most Attended rollup changes. Also drops the now-
unreachable "embed" branches in friendly_label()/iconForLabel().
- analysis.py +17 -4
analysis.py
CHANGED
|
@@ -121,8 +121,6 @@ def friendly_label(raw):
|
|
| 121 |
return "Page footer"
|
| 122 |
if raw == "video":
|
| 123 |
return "Video"
|
| 124 |
-
if raw == "embed":
|
| 125 |
-
return "Embedded content (PDF, player, or widget)"
|
| 126 |
if raw.startswith("img: "):
|
| 127 |
return "Image — " + raw[5:]
|
| 128 |
m = re.match(r"^(h[123]):\s*(.*)$", raw)
|
|
@@ -144,10 +142,25 @@ def friendly_label(raw):
|
|
| 144 |
# =============================================================================
|
| 145 |
|
| 146 |
def _find_aoi(px, py, aois):
|
| 147 |
-
"""Smallest padded AOI containing (px, py), or None. Mirrors the JS hit-test.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 148 |
best = None
|
| 149 |
best_area = None
|
| 150 |
for a in aois:
|
|
|
|
|
|
|
| 151 |
x, y, w, h = a["x"], a["y"], a["w"], a["h"]
|
| 152 |
if (x - PAD_PX) <= px <= (x + w + PAD_PX) and (y - PAD_PX) <= py <= (y + h + PAD_PX):
|
| 153 |
area = w * h
|
|
@@ -821,7 +834,7 @@ const Viewer = (function(){
|
|
| 821 |
function iconForLabel(label){
|
| 822 |
if (!label) return 'click';
|
| 823 |
if (label.indexOf('Image') === 0) return 'image';
|
| 824 |
-
if (label.indexOf('Video') === 0
|
| 825 |
if (label.indexOf('heading') !== -1 || label.indexOf('Heading') === 0 || label.indexOf('Text') === 0) return 'type';
|
| 826 |
if (label.indexOf('Navigation') === 0) return 'menu';
|
| 827 |
if (label.indexOf('Page header') === 0 || label.indexOf('Page footer') === 0) return 'layers';
|
|
|
|
| 121 |
return "Page footer"
|
| 122 |
if raw == "video":
|
| 123 |
return "Video"
|
|
|
|
|
|
|
| 124 |
if raw.startswith("img: "):
|
| 125 |
return "Image — " + raw[5:]
|
| 126 |
m = re.match(r"^(h[123]):\s*(.*)$", raw)
|
|
|
|
| 142 |
# =============================================================================
|
| 143 |
|
| 144 |
def _find_aoi(px, py, aois):
|
| 145 |
+
"""Smallest padded AOI containing (px, py), or None. Mirrors the JS hit-test.
|
| 146 |
+
|
| 147 |
+
Skips raw label "embed": TRACKING_JS's insightuxAOIs() tags every
|
| 148 |
+
<iframe> identically regardless of what's actually inside it or how
|
| 149 |
+
much of the page it covers — it has no visibility into the iframe's
|
| 150 |
+
own content. A single page-spanning iframe (a PDF viewer, an embedded
|
| 151 |
+
system, a video player) then swallows every gaze sample that lands on
|
| 152 |
+
it under one generic "Embedded content" bucket, drowning out anything
|
| 153 |
+
more specific and making Ranked Attention/Most Attended report
|
| 154 |
+
something that isn't a real, distinguishable attention target. Points
|
| 155 |
+
over an iframe just go unlabeled instead (matching what already
|
| 156 |
+
happens over any other untracked area) — the raw gaze samples
|
| 157 |
+
themselves, and the per-segment heatmap that draws them, are
|
| 158 |
+
unaffected either way."""
|
| 159 |
best = None
|
| 160 |
best_area = None
|
| 161 |
for a in aois:
|
| 162 |
+
if a["label"] == "embed":
|
| 163 |
+
continue
|
| 164 |
x, y, w, h = a["x"], a["y"], a["w"], a["h"]
|
| 165 |
if (x - PAD_PX) <= px <= (x + w + PAD_PX) and (y - PAD_PX) <= py <= (y + h + PAD_PX):
|
| 166 |
area = w * h
|
|
|
|
| 834 |
function iconForLabel(label){
|
| 835 |
if (!label) return 'click';
|
| 836 |
if (label.indexOf('Image') === 0) return 'image';
|
| 837 |
+
if (label.indexOf('Video') === 0) return 'video';
|
| 838 |
if (label.indexOf('heading') !== -1 || label.indexOf('Heading') === 0 || label.indexOf('Text') === 0) return 'type';
|
| 839 |
if (label.indexOf('Navigation') === 0) return 'menu';
|
| 840 |
if (label.indexOf('Page header') === 0 || label.indexOf('Page footer') === 0) return 'layers';
|