-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathtask_quality.html
More file actions
186 lines (169 loc) · 7.13 KB
/
task_quality.html
File metadata and controls
186 lines (169 loc) · 7.13 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
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
<!doctype html>
<html>
<head>
<meta charset="utf-8" />
<title>Image Diversity Choice</title>
<meta name="viewport" content="width=device-width,initial-scale=1" />
<style>
body {
font-family: system-ui, -apple-system, Segoe UI, Roboto, Arial, sans-serif;
line-height: 1.45;
margin: 0;
padding: 16px;
max-width: none; /* remove clamp so content can expand within MTurk iframe */
}
h2 { text-align: center; }
.card {
border: 1px solid #ddd;
border-radius: 10px;
padding: 16px;
background: #fff;
text-align: center;
width: min(1800px, 96vw); /* responsive, with a reasonable upper cap */
margin: 0 auto;
}
body {
font-family: system-ui, -apple-system, Segoe UI, Roboto, Arial, sans-serif;
line-height: 1.45;
margin: 0;
padding: 16px;
max-width: none; /* remove clamp so content can expand within MTurk iframe */
}
h2 { text-align: center; }
.card {
border: 1px solid #ddd;
border-radius: 10px;
padding: 16px;
background: #fff;
text-align: center;
width: min(1800px, 96vw); /* responsive, with a reasonable upper cap */
margin: 0 auto;
}
.warn { color:#b45309; background:#fff7ed; border:1px solid #fed7aa; border-radius:8px; padding:10px; margin:10px 0; display:none; }
.ok { color:#065f46; background:#ecfdf5; border:1px solid #a7f3d0; border-radius:8px; padding:10px; margin:10px 0; display:none; }
img {
display: block;
width: 100%;
max-width: 100%;
height: auto;
/* keep image viewable without excessive scrolling (best-effort) */
max-height: calc(96vh - 260px);
border-radius: 6px;
border: 1px solid #eee;
margin: 0 auto;
}
.questionBlock { font-size: 1.15em; }
.radios { display:flex; justify-content:center; gap:20px; margin-top:10px; }
.btn { appearance:none; border:0; background:#10b981; color:#fff; padding:10px 16px; border-radius:8px; font-weight:600; cursor:pointer; }
.btn:disabled { opacity:.6; cursor:not-allowed; }
.lock { color:#b45309; background:#fff7ed; border:1px dashed #fbbf24; border-radius:8px; padding:12px; margin:10px 0; }
.done { margin-top:14px; display:none; }
</style>
</head>
<body>
<h2>Which set of images better matches the shown prompt?</h2>
<!-- Shown if someone skipped consent -->
<div id="locked" class="lock" style="display:none;"></div>
<!-- The actual task -->
<div id="taskCard" class="card" style="display:none;">
<div id="timingWarn" class="warn">
<p>If the image appears small, right-click to open in a new tab.</p>
<p>Tip: Please take a few seconds to view the image carefully before answering.</p>
</div>
<div><img id="compImg" alt="Composite image: left vs right" loading="eager" /></div>
<div class="questionBlock" style="margin-top:14px;">
<p><b>Which set of images better matches the prompt shown?</b></p>
<div class="radios">
<label><input type="radio" name="choice" value="left" required> Left side</label>
<label><input type="radio" name="choice" value="right" required> Right side</label>
<label><input type="radio" name="choice" value="same" required> About the same</label>
</div>
</div>
<div style="margin-top:16px;">
<button class="btn" id="submitBtn">Submit</button>
</div>
<div id="doneMsg" class="done">
<h3>Thanks — your response was recorded.</h3>
<p>If this page is not embedded in MTurk, you may now close the tab.</p>
</div>
</div>
<script>
// Force the iframe viewport to the top when this page loads (MTurk iframes can preserve scroll)
if ('scrollRestoration' in history) history.scrollRestoration = 'manual';
window.addEventListener('load', () => window.scrollTo(0, 0));
// Helpers
const qp = (k,d="") => new URL(location.href).searchParams.get(k) ?? d;
// Params passed from pis.html
const assignmentId = qp('assignmentId'); // may be empty in iframe method; MTurk outer page has it
const workerId = qp('workerId');
const hitId = qp('hitId');
const trialId = qp('trial_id');
const compositeUrl = qp('composite_url');
const pisUrl = qp('pis_url');
const consented = qp('consented') === '1';
const tokenParam = qp('t');
const tokenStored = sessionStorage.getItem('consent_token');
const lockedEl = document.getElementById('locked');
const taskEl = document.getElementById('taskCard');
// Build safe link back to PIS (keeps /ideate-images/ path)
function backToPISUrl(){
const u = new URL(window.location.href);
u.pathname = u.pathname.replace(/[^/]+$/, 'pis_quality.html');
u.search = '';
[
['assignmentId', assignmentId],
['workerId', workerId],
['hitId', hitId],
['trial_id', trialId],
['composite_url',compositeUrl],
['pis_url', pisUrl]
].forEach(([k,v]) => { if (v) u.searchParams.set(k, v); });
return u.toString();
}
const unlocked = consented && tokenParam && tokenStored && (tokenParam === tokenStored);
if (!unlocked){
lockedEl.style.display = 'block';
lockedEl.innerHTML = `This page can only be accessed after completing the PIS & consent step.<br>
<a href="${backToPISUrl()}" style="display:inline-block;margin-top:8px;">Go to PIS & consent</a>`;
} else {
// Show task
taskEl.style.display = 'block';
// Ensure we start at the top even if the previous page was scrolled
requestAnimationFrame(() => window.scrollTo(0, 0));
// Load image
document.getElementById('compImg').src = compositeUrl;
// Timing
const start = Date.now();
// Submit -> send to parent MTurk page via postMessage
document.getElementById('submitBtn').addEventListener('click', () => {
const selected = document.querySelector('input[name="choice"]:checked')?.value;
if (!selected){ alert('Please select one option.'); return; }
const end = Date.now();
const payload = {
trial_id: trialId || '',
composite_url: compositeUrl || '',
choice: selected,
time_started_ms: String(start),
time_submitted_ms: String(end),
time_spent_seconds: String(Math.max(0, Math.round((end - start)/1000))),
consent_token: tokenParam || '',
pis_url: pisUrl || ''
};
if (window.parent && window.parent !== window) {
window.parent.postMessage({ type: 'mturk-submit', payload }, '*');
// Disable UI and show a small message while parent submits
document.getElementById('submitBtn').disabled = true;
const done = document.getElementById('doneMsg'); done.style.display = 'block';
done.innerHTML = '<h3>Submitting…</h3><p>Please wait.</p>';
} else {
// Fallback if opened standalone
document.getElementById('submitBtn').disabled = true;
const done = document.getElementById('doneMsg'); done.style.display = 'block';
done.innerHTML = '<h3>Thanks — your response was recorded.</h3><p>You may close this tab.</p>';
console.log('Payload (standalone):', payload);
}
});
}
</script>
</body>
</html>