Mercurial > hg > webaudioevaluationtool
comparison interfaces/ABX.js @ 2538:464c6c6692d6
Beautified entire project.
author | Nicholas Jillings <nicholas.jillings@mail.bcu.ac.uk> |
---|---|
date | Mon, 14 Nov 2016 14:17:03 +0000 |
parents | 42abe6eddfb5 |
children | 342ef7948c47 |
comparison
equal
deleted
inserted
replaced
2536:527020a63203 | 2538:464c6c6692d6 |
---|---|
5 | 5 |
6 // Once this is loaded and parsed, begin execution | 6 // Once this is loaded and parsed, begin execution |
7 loadInterface(); | 7 loadInterface(); |
8 | 8 |
9 function loadInterface() { | 9 function loadInterface() { |
10 // Use this to do any one-time page / element construction. For instance, placing any stationary text objects, | 10 // Use this to do any one-time page / element construction. For instance, placing any stationary text objects, |
11 // holding div's, or setting up any nodes which are present for the entire test sequence | 11 // holding div's, or setting up any nodes which are present for the entire test sequence |
12 | 12 |
13 interfaceContext.insertPoint.innerHTML = ""; // Clear the current schema | 13 interfaceContext.insertPoint.innerHTML = ""; // Clear the current schema |
14 | 14 |
15 Interface.prototype.checkScaleRange = function(min, max) { | 15 Interface.prototype.checkScaleRange = function (min, max) { |
16 var page = testState.getCurrentTestPage(); | 16 var page = testState.getCurrentTestPage(); |
17 var audioObjects = audioEngineContext.audioObjects; | 17 var audioObjects = audioEngineContext.audioObjects; |
18 var state = true; | 18 var state = true; |
19 var str = "Please keep listening. "; | 19 var str = "Please keep listening. "; |
20 var minRanking = Infinity; | 20 var minRanking = Infinity; |
21 var maxRanking = -Infinity; | 21 var maxRanking = -Infinity; |
22 for (var ao of audioObjects) { | 22 for (var ao of audioObjects) { |
23 var rank = ao.interfaceDOM.getValue(); | 23 var rank = ao.interfaceDOM.getValue(); |
24 if (rank < minRanking) {minRanking = rank;} | 24 if (rank < minRanking) { |
25 if (rank > maxRanking) {maxRanking = rank;} | 25 minRanking = rank; |
26 } | 26 } |
27 if (maxRanking*100 < max) { | 27 if (rank > maxRanking) { |
28 maxRanking = rank; | |
29 } | |
30 } | |
31 if (maxRanking * 100 < max) { | |
28 str += "At least one fragment must be selected." | 32 str += "At least one fragment must be selected." |
29 state = false; | 33 state = false; |
30 } | 34 } |
31 if (!state) { | 35 if (!state) { |
32 console.log(str); | 36 console.log(str); |
33 this.storeErrorNode(str); | 37 this.storeErrorNode(str); |
34 interfaceContext.lightbox.post("Message",str); | 38 interfaceContext.lightbox.post("Message", str); |
35 } | 39 } |
36 return state; | 40 return state; |
37 } | 41 } |
38 | 42 |
39 // Custom comparator Object | 43 // Custom comparator Object |
40 Interface.prototype.comparator = null; | 44 Interface.prototype.comparator = null; |
41 | 45 |
42 // The injection point into the HTML page | 46 // The injection point into the HTML page |
43 interfaceContext.insertPoint = document.getElementById("topLevelBody"); | 47 interfaceContext.insertPoint = document.getElementById("topLevelBody"); |
44 var testContent = document.createElement('div'); | 48 var testContent = document.createElement('div'); |
45 testContent.id = 'testContent'; | 49 testContent.id = 'testContent'; |
46 | 50 |
47 // Create the top div for the Title element | 51 // Create the top div for the Title element |
48 var titleAttr = specification.title; | 52 var titleAttr = specification.title; |
49 var title = document.createElement('div'); | 53 var title = document.createElement('div'); |
50 title.className = "title"; | 54 title.className = "title"; |
51 title.align = "center"; | 55 title.align = "center"; |
52 var titleSpan = document.createElement('span'); | 56 var titleSpan = document.createElement('span'); |
53 titleSpan.id = "test-title"; | 57 titleSpan.id = "test-title"; |
54 | 58 |
55 // Set title to that defined in XML, else set to default | 59 // Set title to that defined in XML, else set to default |
56 if (titleAttr != undefined) { | 60 if (titleAttr != undefined) { |
57 titleSpan.textContent = titleAttr; | 61 titleSpan.textContent = titleAttr; |
58 } else { | 62 } else { |
59 titleSpan.textContent = 'Listening test'; | 63 titleSpan.textContent = 'Listening test'; |
60 } | 64 } |
61 // Insert the titleSpan element into the title div element. | 65 // Insert the titleSpan element into the title div element. |
62 title.appendChild(titleSpan); | 66 title.appendChild(titleSpan); |
63 | 67 |
64 var pagetitle = document.createElement('div'); | 68 var pagetitle = document.createElement('div'); |
65 pagetitle.className = "pageTitle"; | 69 pagetitle.className = "pageTitle"; |
66 pagetitle.align = "center"; | 70 pagetitle.align = "center"; |
67 var titleSpan = document.createElement('span'); | 71 var titleSpan = document.createElement('span'); |
68 titleSpan.id = "pageTitle"; | 72 titleSpan.id = "pageTitle"; |
69 pagetitle.appendChild(titleSpan); | 73 pagetitle.appendChild(titleSpan); |
70 | 74 |
71 // Create Interface buttons! | 75 // Create Interface buttons! |
72 var interfaceButtons = document.createElement('div'); | 76 var interfaceButtons = document.createElement('div'); |
73 interfaceButtons.id = 'interface-buttons'; | 77 interfaceButtons.id = 'interface-buttons'; |
74 interfaceButtons.style.height = '25px'; | 78 interfaceButtons.style.height = '25px'; |
75 | 79 |
76 // Create playback start/stop points | 80 // Create playback start/stop points |
77 var playback = document.createElement("button"); | 81 var playback = document.createElement("button"); |
78 playback.innerHTML = 'Stop'; | 82 playback.innerHTML = 'Stop'; |
79 playback.id = 'playback-button'; | 83 playback.id = 'playback-button'; |
80 playback.style.float = 'left'; | 84 playback.style.float = 'left'; |
81 // onclick function. Check if it is playing or not, call the correct function in the | 85 // onclick function. Check if it is playing or not, call the correct function in the |
82 // audioEngine, change the button text to reflect the next state. | 86 // audioEngine, change the button text to reflect the next state. |
83 playback.onclick = function() { | 87 playback.onclick = function () { |
84 if (audioEngineContext.status == 1) { | 88 if (audioEngineContext.status == 1) { |
85 audioEngineContext.stop(); | 89 audioEngineContext.stop(); |
86 this.innerHTML = 'Stop'; | 90 this.innerHTML = 'Stop'; |
87 var time = audioEngineContext.timer.getTestTime(); | 91 var time = audioEngineContext.timer.getTestTime(); |
88 console.log('Stopped at ' + time); // DEBUG/SAFETY | 92 console.log('Stopped at ' + time); // DEBUG/SAFETY |
89 } | 93 } |
90 }; | 94 }; |
91 // Append the interface buttons into the interfaceButtons object. | 95 // Append the interface buttons into the interfaceButtons object. |
92 interfaceButtons.appendChild(playback); | 96 interfaceButtons.appendChild(playback); |
93 | 97 |
94 // Global parent for the comment boxes on the page | 98 // Global parent for the comment boxes on the page |
95 var feedbackHolder = document.createElement('div'); | 99 var feedbackHolder = document.createElement('div'); |
96 feedbackHolder.id = 'feedbackHolder'; | 100 feedbackHolder.id = 'feedbackHolder'; |
97 | 101 |
98 // Construct the AB Boxes | 102 // Construct the AB Boxes |
99 var boxes = document.createElement('div'); | 103 var boxes = document.createElement('div'); |
100 boxes.align = "center"; | 104 boxes.align = "center"; |
101 boxes.id = "box-holders"; | 105 boxes.id = "box-holders"; |
102 boxes.style.float = "left"; | 106 boxes.style.float = "left"; |
103 | 107 |
104 var submit = document.createElement('button'); | 108 var submit = document.createElement('button'); |
105 submit.id = "submit"; | 109 submit.id = "submit"; |
106 submit.onclick = buttonSubmitClick; | 110 submit.onclick = buttonSubmitClick; |
107 submit.className = "big-button"; | 111 submit.className = "big-button"; |
108 submit.textContent = "submit"; | 112 submit.textContent = "submit"; |
109 submit.style.position = "relative"; | 113 submit.style.position = "relative"; |
110 submit.style.left = (window.innerWidth-250)/2 + 'px'; | 114 submit.style.left = (window.innerWidth - 250) / 2 + 'px'; |
111 | 115 |
112 feedbackHolder.appendChild(boxes); | 116 feedbackHolder.appendChild(boxes); |
113 | 117 |
114 // Create holder for comment boxes | 118 // Create holder for comment boxes |
115 var comments = document.createElement("div"); | 119 var comments = document.createElement("div"); |
116 comments.id = "comment-box-holder"; | 120 comments.id = "comment-box-holder"; |
117 | 121 |
118 // Inject into HTML | 122 // Inject into HTML |
119 testContent.appendChild(title); // Insert the title | 123 testContent.appendChild(title); // Insert the title |
120 testContent.appendChild(pagetitle); | 124 testContent.appendChild(pagetitle); |
121 testContent.appendChild(interfaceButtons); | 125 testContent.appendChild(interfaceButtons); |
122 testContent.appendChild(feedbackHolder); | 126 testContent.appendChild(feedbackHolder); |
123 testContent.appendChild(submit); | 127 testContent.appendChild(submit); |
124 testContent.appendChild(comments); | 128 testContent.appendChild(comments); |
125 interfaceContext.insertPoint.appendChild(testContent); | 129 interfaceContext.insertPoint.appendChild(testContent); |
126 | 130 |
127 // Load the full interface | 131 // Load the full interface |
128 testState.initialise(); | 132 testState.initialise(); |
129 testState.advanceState(); | 133 testState.advanceState(); |
130 }; | 134 }; |
131 | 135 |
132 function loadTest(page) | 136 function loadTest(page) { |
133 { | 137 // Called each time a new test page is to be build. The page specification node is the only item passed in |
134 // Called each time a new test page is to be build. The page specification node is the only item passed in | |
135 document.getElementById('box-holders').innerHTML = ""; | 138 document.getElementById('box-holders').innerHTML = ""; |
136 | 139 |
137 var interfaceObj = page.interfaces; | 140 var interfaceObj = page.interfaces; |
138 if (interfaceObj.length > 1) | 141 if (interfaceObj.length > 1) { |
139 { | 142 console.log("WARNING - This interface only supports one <interface> node per page. Using first interface node"); |
140 console.log("WARNING - This interface only supports one <interface> node per page. Using first interface node"); | 143 } |
141 } | 144 interfaceObj = interfaceObj[0]; |
142 interfaceObj = interfaceObj[0]; | 145 |
143 | |
144 var commentHolder = document.getElementById("comment-box-holder"); | 146 var commentHolder = document.getElementById("comment-box-holder"); |
145 commentHolder.innerHTML = ""; | 147 commentHolder.innerHTML = ""; |
146 | 148 |
147 // Set the page title | 149 // Set the page title |
148 if (typeof page.title == "string" && page.title.length > 0) { | 150 if (typeof page.title == "string" && page.title.length > 0) { |
149 document.getElementById("test-title").textContent = page.title | 151 document.getElementById("test-title").textContent = page.title |
150 } | 152 } |
151 | 153 |
152 if(interfaceObj.title != null) | 154 if (interfaceObj.title != null) { |
153 { | 155 document.getElementById("pageTitle").textContent = interfaceObj.title; |
154 document.getElementById("pageTitle").textContent = interfaceObj.title; | 156 } |
155 } | 157 |
156 | |
157 interfaceContext.comparator = new comparator(page); | 158 interfaceContext.comparator = new comparator(page); |
158 | 159 |
159 var interfaceOptions = specification.interfaces.options.concat(interfaceObj.options); | 160 var interfaceOptions = specification.interfaces.options.concat(interfaceObj.options); |
160 for (var option of interfaceOptions) | 161 for (var option of interfaceOptions) { |
161 { | 162 if (option.type == "show") { |
162 if (option.type == "show") | 163 switch (option.name) { |
163 { | |
164 switch(option.name) { | |
165 case "playhead": | 164 case "playhead": |
166 var playbackHolder = document.getElementById('playback-holder'); | 165 var playbackHolder = document.getElementById('playback-holder'); |
167 if (playbackHolder == null) | 166 if (playbackHolder == null) { |
168 { | |
169 playbackHolder = document.createElement('div'); | 167 playbackHolder = document.createElement('div'); |
170 playbackHolder.style.width = "100%"; | 168 playbackHolder.style.width = "100%"; |
171 playbackHolder.style.float = "left"; | 169 playbackHolder.style.float = "left"; |
172 playbackHolder.align = 'center'; | 170 playbackHolder.align = 'center'; |
173 playbackHolder.appendChild(interfaceContext.playhead.object); | 171 playbackHolder.appendChild(interfaceContext.playhead.object); |
174 feedbackHolder.appendChild(playbackHolder); | 172 feedbackHolder.appendChild(playbackHolder); |
175 } | 173 } |
176 break; | 174 break; |
177 case "page-count": | 175 case "page-count": |
178 var pagecountHolder = document.getElementById('page-count'); | 176 var pagecountHolder = document.getElementById('page-count'); |
179 if (pagecountHolder == null) | 177 if (pagecountHolder == null) { |
180 { | |
181 pagecountHolder = document.createElement('div'); | 178 pagecountHolder = document.createElement('div'); |
182 pagecountHolder.id = 'page-count'; | 179 pagecountHolder.id = 'page-count'; |
183 } | 180 } |
184 pagecountHolder.innerHTML = '<span>Page '+(testState.stateIndex+1)+' of '+testState.stateMap.length+'</span>'; | 181 pagecountHolder.innerHTML = '<span>Page ' + (testState.stateIndex + 1) + ' of ' + testState.stateMap.length + '</span>'; |
185 var inject = document.getElementById('interface-buttons'); | 182 var inject = document.getElementById('interface-buttons'); |
186 inject.appendChild(pagecountHolder); | 183 inject.appendChild(pagecountHolder); |
187 break; | 184 break; |
188 case "volume": | 185 case "volume": |
189 if (document.getElementById('master-volume-holder') == null) | 186 if (document.getElementById('master-volume-holder') == null) { |
190 { | |
191 feedbackHolder.appendChild(interfaceContext.volume.object); | 187 feedbackHolder.appendChild(interfaceContext.volume.object); |
192 } | 188 } |
193 break; | 189 break; |
194 case "comments": | 190 case "comments": |
195 // Generate one comment box per presented page | 191 // Generate one comment box per presented page |
196 for (var element of audioEngineContext.audioObjects) | 192 for (var element of audioEngineContext.audioObjects) { |
197 { | |
198 interfaceContext.commentBoxes.createCommentBox(element); | 193 interfaceContext.commentBoxes.createCommentBox(element); |
199 } | 194 } |
200 interfaceContext.commentBoxes.showCommentBoxes(commentHolder,true); | 195 interfaceContext.commentBoxes.showCommentBoxes(commentHolder, true); |
201 break; | 196 break; |
202 } | 197 } |
203 } | 198 } |
204 } | 199 } |
205 | 200 |
206 $(page.commentQuestions).each(function(index,element) { | 201 $(page.commentQuestions).each(function (index, element) { |
207 var node = interfaceContext.createCommentQuestion(element); | 202 var node = interfaceContext.createCommentQuestion(element); |
208 commentHolder.appendChild(node.holder); | 203 commentHolder.appendChild(node.holder); |
209 }); | 204 }); |
210 | 205 |
211 resizeWindow(null); | 206 resizeWindow(null); |
212 } | 207 } |
213 | 208 |
214 function comparator(page) | 209 function comparator(page) { |
215 { | |
216 // Build prototype constructor | 210 // Build prototype constructor |
217 this.interfaceObject = function(element,label) | 211 this.interfaceObject = function (element, label) { |
218 { | |
219 // An example node, you can make this however you want for each audioElement. | 212 // An example node, you can make this however you want for each audioElement. |
220 // However, every audioObject (audioEngineContext.audioObject) MUST have an interface object with the following | 213 // However, every audioObject (audioEngineContext.audioObject) MUST have an interface object with the following |
221 // You attach them by calling audioObject.bindInterface( ) | 214 // You attach them by calling audioObject.bindInterface( ) |
222 this.parent = element; | 215 this.parent = element; |
223 this.id = element.id; | 216 this.id = element.id; |
224 this.value = 0; | 217 this.value = 0; |
225 this.disabled = true; | 218 this.disabled = true; |
226 this.box = document.createElement('div'); | 219 this.box = document.createElement('div'); |
227 this.box.className = 'comparator-holder'; | 220 this.box.className = 'comparator-holder'; |
228 this.box.setAttribute('track-id',element.id); | 221 this.box.setAttribute('track-id', element.id); |
229 this.box.id = 'comparator-'+label; | 222 this.box.id = 'comparator-' + label; |
230 this.selector = document.createElement('div'); | 223 this.selector = document.createElement('div'); |
231 this.selector.className = 'comparator-selector disabled'; | 224 this.selector.className = 'comparator-selector disabled'; |
232 var selectorText = document.createElement('span'); | 225 var selectorText = document.createElement('span'); |
233 selectorText.textContent = label; | 226 selectorText.textContent = label; |
234 this.selector.appendChild(selectorText); | 227 this.selector.appendChild(selectorText); |
235 this.playback = document.createElement('button'); | 228 this.playback = document.createElement('button'); |
236 this.playback.className = 'comparator-button'; | 229 this.playback.className = 'comparator-button'; |
237 this.playback.disabled = true; | 230 this.playback.disabled = true; |
238 this.playback.textContent = "Listen"; | 231 this.playback.textContent = "Listen"; |
239 this.box.appendChild(this.selector); | 232 this.box.appendChild(this.selector); |
240 this.box.appendChild(this.playback); | 233 this.box.appendChild(this.playback); |
241 this.selector.onclick = function(event) | 234 this.selector.onclick = function (event) { |
242 { | |
243 var label = event.currentTarget.children[0].textContent; | 235 var label = event.currentTarget.children[0].textContent; |
244 if (label == "X" || label == "x") {return;} | 236 if (label == "X" || label == "x") { |
245 var time = audioEngineContext.timer.getTestTime(); | 237 return; |
246 if ($(event.currentTarget).hasClass('disabled')) | 238 } |
247 { | 239 var time = audioEngineContext.timer.getTestTime(); |
248 console.log("Please wait until sample has loaded"); | 240 if ($(event.currentTarget).hasClass('disabled')) { |
249 return; | 241 console.log("Please wait until sample has loaded"); |
250 } | 242 return; |
251 if (audioEngineContext.status == 0) | 243 } |
252 { | 244 if (audioEngineContext.status == 0) { |
253 interfaceContext.lightbox.post("Message", "Please listen to the samples before making a selection"); | 245 interfaceContext.lightbox.post("Message", "Please listen to the samples before making a selection"); |
254 console.log("Please listen to the samples before making a selection"); | 246 console.log("Please listen to the samples before making a selection"); |
255 return; | 247 return; |
256 } | 248 } |
257 var id = event.currentTarget.parentElement.getAttribute('track-id'); | 249 var id = event.currentTarget.parentElement.getAttribute('track-id'); |
258 interfaceContext.comparator.selected = id; | 250 interfaceContext.comparator.selected = id; |
259 if ($(event.currentTarget).hasClass("selected")) { | 251 if ($(event.currentTarget).hasClass("selected")) { |
260 $(".comparator-selector").removeClass('selected'); | 252 $(".comparator-selector").removeClass('selected'); |
261 for (var i=0; i<interfaceContext.comparator.pair.length; i++) | 253 for (var i = 0; i < interfaceContext.comparator.pair.length; i++) { |
262 { | |
263 var obj = interfaceContext.comparator.pair[i]; | 254 var obj = interfaceContext.comparator.pair[i]; |
264 obj.parent.metric.moved(time,0); | 255 obj.parent.metric.moved(time, 0); |
265 obj.value = 0; | 256 obj.value = 0; |
266 } | 257 } |
267 } else { | 258 } else { |
268 $(".comparator-selector").removeClass('selected'); | 259 $(".comparator-selector").removeClass('selected'); |
269 $(event.currentTarget).addClass('selected'); | 260 $(event.currentTarget).addClass('selected'); |
270 for (var i=0; i<interfaceContext.comparator.pair.length; i++) | 261 for (var i = 0; i < interfaceContext.comparator.pair.length; i++) { |
271 { | |
272 var obj = interfaceContext.comparator.pair[i]; | 262 var obj = interfaceContext.comparator.pair[i]; |
273 if (i == id) { | 263 if (i == id) { |
274 obj.value = 1; | 264 obj.value = 1; |
275 } else { | 265 } else { |
276 obj.value = 0; | 266 obj.value = 0; |
277 } | 267 } |
278 obj.parent.metric.moved(time,obj.value); | 268 obj.parent.metric.moved(time, obj.value); |
279 } | 269 } |
280 console.log("Selected "+id+' ('+time+')'); | 270 console.log("Selected " + id + ' (' + time + ')'); |
281 } | 271 } |
282 }; | 272 }; |
283 this.playback.setAttribute("playstate","ready"); | 273 this.playback.setAttribute("playstate", "ready"); |
284 this.playback.onclick = function(event) | 274 this.playback.onclick = function (event) { |
285 { | 275 var id = event.currentTarget.parentElement.getAttribute('track-id'); |
286 var id = event.currentTarget.parentElement.getAttribute('track-id'); | 276 if (event.currentTarget.getAttribute("playstate") == "ready") { |
287 if (event.currentTarget.getAttribute("playstate") == "ready") | |
288 { | |
289 audioEngineContext.play(id); | 277 audioEngineContext.play(id); |
290 } else if (event.currentTarget.getAttribute("playstate") == "playing") { | 278 } else if (event.currentTarget.getAttribute("playstate") == "playing") { |
291 audioEngineContext.stop(); | 279 audioEngineContext.stop(); |
292 } | 280 } |
293 | 281 |
294 }; | 282 }; |
295 this.enable = function() | 283 this.enable = function () { |
296 { | |
297 // This is used to tell the interface object that playback of this node is ready | 284 // This is used to tell the interface object that playback of this node is ready |
298 if (this.parent.state == 1) | 285 if (this.parent.state == 1) { |
299 { | 286 $(this.selector).removeClass('disabled'); |
300 $(this.selector).removeClass('disabled'); | 287 this.playback.disabled = false; |
301 this.playback.disabled = false; | 288 } |
302 } | 289 }; |
303 }; | 290 this.updateLoading = function (progress) { |
304 this.updateLoading = function(progress) | |
305 { | |
306 // progress is a value from 0 to 100 indicating the current download state of media files | 291 // progress is a value from 0 to 100 indicating the current download state of media files |
307 if (progress != 100) | 292 if (progress != 100) { |
308 { | 293 progress = String(progress); |
309 progress = String(progress); | 294 progress = progress.split('.')[0]; |
310 progress = progress.split('.')[0]; | 295 this.playback.textContent = progress + '%'; |
311 this.playback.textContent = progress+'%'; | 296 } else { |
312 } else { | 297 this.playback.textContent = "Play"; |
313 this.playback.textContent = "Play"; | 298 } |
314 } | 299 }; |
315 }; | 300 this.error = function () { |
316 this.error = function() { | |
317 // audioObject has an error!! | 301 // audioObject has an error!! |
318 this.playback.textContent = "Error"; | 302 this.playback.textContent = "Error"; |
319 $(this.playback).addClass("error-colour"); | 303 $(this.playback).addClass("error-colour"); |
320 }; | 304 }; |
321 this.startPlayback = function() | 305 this.startPlayback = function () { |
322 { | |
323 if (this.parent.specification.parent.playOne || specification.playOne) { | 306 if (this.parent.specification.parent.playOne || specification.playOne) { |
324 $('.comparator-button').text('Wait'); | 307 $('.comparator-button').text('Wait'); |
325 $('.comparator-button').attr("disabled","true"); | 308 $('.comparator-button').attr("disabled", "true"); |
326 $(this.playback).removeAttr("disabled"); | 309 $(this.playback).removeAttr("disabled"); |
327 } else { | 310 } else { |
328 $('.comparator-button').text('Listen'); | 311 $('.comparator-button').text('Listen'); |
329 } | 312 } |
330 $(this.playback).text('Stop'); | 313 $(this.playback).text('Stop'); |
331 this.playback.setAttribute("playstate","playing"); | 314 this.playback.setAttribute("playstate", "playing"); |
332 }; | 315 }; |
333 this.stopPlayback = function() | 316 this.stopPlayback = function () { |
334 { | |
335 if (this.playback.getAttribute("playstate") == "playing") { | 317 if (this.playback.getAttribute("playstate") == "playing") { |
336 $('.comparator-button').text('Listen'); | 318 $('.comparator-button').text('Listen'); |
337 $('.comparator-button').removeAttr("disabled"); | 319 $('.comparator-button').removeAttr("disabled"); |
338 this.playback.setAttribute("playstate","ready"); | 320 this.playback.setAttribute("playstate", "ready"); |
339 } | 321 } |
340 }; | 322 }; |
341 this.getValue = function() | 323 this.getValue = function () { |
342 { | |
343 // Return the current value of the object. If there is no value, return 0 | 324 // Return the current value of the object. If there is no value, return 0 |
344 return this.value; | 325 return this.value; |
345 }; | 326 }; |
346 this.getPresentedId = function() | 327 this.getPresentedId = function () { |
347 { | |
348 // Return the presented ID of the object. For instance, the APE has sliders starting from 0. Whilst AB has alphabetical scale | 328 // Return the presented ID of the object. For instance, the APE has sliders starting from 0. Whilst AB has alphabetical scale |
349 return this.selector.children[0].textContent; | 329 return this.selector.children[0].textContent; |
350 }; | 330 }; |
351 this.canMove = function() | 331 this.canMove = function () { |
352 { | |
353 // Return either true or false if the interface object can be moved. AB / Reference cannot, whilst sliders can and therefore have a continuous scale. | 332 // Return either true or false if the interface object can be moved. AB / Reference cannot, whilst sliders can and therefore have a continuous scale. |
354 // These are checked primarily if the interface check option 'fragmentMoved' is enabled. | 333 // These are checked primarily if the interface check option 'fragmentMoved' is enabled. |
355 return false; | 334 return false; |
356 }; | 335 }; |
357 this.exportXMLDOM = function(audioObject) { | 336 this.exportXMLDOM = function (audioObject) { |
358 // Called by the audioObject holding this element to export the interface <value> node. | 337 // Called by the audioObject holding this element to export the interface <value> node. |
359 // If there is no value node (such as outside reference), return null | 338 // If there is no value node (such as outside reference), return null |
360 // If there are multiple value nodes (such as multiple scale / 2D scales), return an array of nodes with each value node having an 'interfaceName' attribute | 339 // If there are multiple value nodes (such as multiple scale / 2D scales), return an array of nodes with each value node having an 'interfaceName' attribute |
361 // Use storage.document.createElement('value'); to generate the XML node. | 340 // Use storage.document.createElement('value'); to generate the XML node. |
362 var node = storage.document.createElement('value'); | 341 var node = storage.document.createElement('value'); |
363 node.textContent = this.value; | 342 node.textContent = this.value; |
364 return node; | 343 return node; |
365 | 344 |
366 }; | 345 }; |
367 this.error = function() { | 346 this.error = function () { |
368 // If there is an error with the audioObject, this will be called to indicate a failure | 347 // If there is an error with the audioObject, this will be called to indicate a failure |
369 } | 348 } |
370 }; | 349 }; |
371 // Ensure there are only two comparisons per page | 350 // Ensure there are only two comparisons per page |
372 if (page.audioElements.length != 2) { | 351 if (page.audioElements.length != 2) { |
373 console.error('FATAL - There must be 2 <audioelement> nodes on each <page>: '+page.id); | 352 console.error('FATAL - There must be 2 <audioelement> nodes on each <page>: ' + page.id); |
374 return; | 353 return; |
375 } | 354 } |
376 // Build the three audio elements | 355 // Build the three audio elements |
377 this.pair = []; | 356 this.pair = []; |
378 this.X = null; | 357 this.X = null; |
379 this.boxHolders = document.getElementById('box-holders'); | 358 this.boxHolders = document.getElementById('box-holders'); |
380 for (var index=0; index<page.audioElements.length; index++) { | 359 for (var index = 0; index < page.audioElements.length; index++) { |
381 var element = page.audioElements[index]; | 360 var element = page.audioElements[index]; |
382 if (element.type != 'normal') | 361 if (element.type != 'normal') { |
383 { | 362 console.log("WARNING - ABX can only have normal elements. Page " + page.id + ", Element " + element.id); |
384 console.log("WARNING - ABX can only have normal elements. Page "+page.id+", Element "+element.id); | |
385 element.type = "normal"; | 363 element.type = "normal"; |
386 } | 364 } |
387 var audioObject = audioEngineContext.newTrack(element); | 365 var audioObject = audioEngineContext.newTrack(element); |
388 var label; | 366 var label; |
389 switch(audioObject.specification.parent.label) { | 367 switch (audioObject.specification.parent.label) { |
390 case "none": | 368 case "none": |
391 label = ""; | 369 label = ""; |
392 break; | 370 break; |
393 case "number": | 371 case "number": |
394 label = ""+index; | 372 label = "" + index; |
395 break; | 373 break; |
396 case "letter": | 374 case "letter": |
397 label = String.fromCharCode(97 + index); | 375 label = String.fromCharCode(97 + index); |
398 break; | 376 break; |
399 default: | 377 default: |
400 label = String.fromCharCode(65 + index); | 378 label = String.fromCharCode(65 + index); |
401 break; | 379 break; |
402 } | 380 } |
403 var node = new this.interfaceObject(audioObject,label); | 381 var node = new this.interfaceObject(audioObject, label); |
404 audioObject.bindInterface(node); | 382 audioObject.bindInterface(node); |
405 this.pair.push(node); | 383 this.pair.push(node); |
406 this.boxHolders.appendChild(node.box); | 384 this.boxHolders.appendChild(node.box); |
407 } | 385 } |
408 var elementId = Math.floor(Math.random() * 2); //Randomly pick A or B to be X | 386 var elementId = Math.floor(Math.random() * 2); //Randomly pick A or B to be X |
409 var element = new page.audioElementNode(specification); | 387 var element = new page.audioElementNode(specification); |
410 for (var atr in page.audioElements[elementId]) { | 388 for (var atr in page.audioElements[elementId]) { |
411 eval("element."+atr+" = page.audioElements[elementId]."+atr); | 389 eval("element." + atr + " = page.audioElements[elementId]." + atr); |
412 } | 390 } |
413 element.id += "-X"; | 391 element.id += "-X"; |
414 if (typeof element.name == "string") {element.name+="-X";} | 392 if (typeof element.name == "string") { |
393 element.name += "-X"; | |
394 } | |
415 page.audioElements.push(element); | 395 page.audioElements.push(element); |
416 // Create the save place-holder for the 'X' element | 396 // Create the save place-holder for the 'X' element |
417 var root = testState.currentStore.XMLDOM; | 397 var root = testState.currentStore.XMLDOM; |
418 var aeNode = storage.document.createElement('audioelement'); | 398 var aeNode = storage.document.createElement('audioelement'); |
419 aeNode.setAttribute('ref',element.id); | 399 aeNode.setAttribute('ref', element.id); |
420 if (typeof element.name == "string"){aeNode.setAttribute('name',element.name);} | 400 if (typeof element.name == "string") { |
421 aeNode.setAttribute('type','normal'); | 401 aeNode.setAttribute('name', element.name); |
422 aeNode.setAttribute('url',element.url); | 402 } |
423 aeNode.setAttribute('gain',element.gain); | 403 aeNode.setAttribute('type', 'normal'); |
404 aeNode.setAttribute('url', element.url); | |
405 aeNode.setAttribute('gain', element.gain); | |
424 aeNode.appendChild(storage.document.createElement('metric')); | 406 aeNode.appendChild(storage.document.createElement('metric')); |
425 root.appendChild(aeNode); | 407 root.appendChild(aeNode); |
426 // Build the 'X' element | 408 // Build the 'X' element |
427 var audioObject = audioEngineContext.newTrack(element); | 409 var audioObject = audioEngineContext.newTrack(element); |
428 var label; | 410 var label; |
429 switch(audioObject.specification.parent.label) { | 411 switch (audioObject.specification.parent.label) { |
430 case "letter": | 412 case "letter": |
431 label = "x"; | 413 label = "x"; |
432 break; | 414 break; |
433 default: | 415 default: |
434 label = "X"; | 416 label = "X"; |
435 break; | 417 break; |
436 } | 418 } |
437 var node = new this.interfaceObject(audioObject,label); | 419 var node = new this.interfaceObject(audioObject, label); |
438 node.box.children[0].classList.add('inactive'); | 420 node.box.children[0].classList.add('inactive'); |
439 audioObject.bindInterface(node); | 421 audioObject.bindInterface(node); |
440 this.X = node; | 422 this.X = node; |
441 this.boxHolders.appendChild(node.box); | 423 this.boxHolders.appendChild(node.box); |
442 } | 424 } |
443 | 425 |
444 function resizeWindow(event) | 426 function resizeWindow(event) { |
445 { | 427 document.getElementById('submit').style.left = (window.innerWidth - 250) / 2 + 'px'; |
446 document.getElementById('submit').style.left = (window.innerWidth-250)/2 + 'px'; | 428 var numObj = 3; |
447 var numObj = 3; | 429 var boxW = numObj * 312; |
448 var boxW = numObj*312; | |
449 var diff = window.innerWidth - boxW; | 430 var diff = window.innerWidth - boxW; |
450 while (diff < 0) | 431 while (diff < 0) { |
451 { | 432 numObj = Math.ceil(numObj / 2); |
452 numObj = Math.ceil(numObj/2); | 433 boxW = numObj * 312; |
453 boxW = numObj*312; | |
454 diff = window.innerWidth - boxW; | 434 diff = window.innerWidth - boxW; |
455 } | 435 } |
456 document.getElementById('box-holders').style.marginLeft = diff/2 + 'px'; | 436 document.getElementById('box-holders').style.marginLeft = diff / 2 + 'px'; |
457 document.getElementById('box-holders').style.marginRight = diff/2 + 'px'; | 437 document.getElementById('box-holders').style.marginRight = diff / 2 + 'px'; |
458 document.getElementById('box-holders').style.width = boxW + 'px'; | 438 document.getElementById('box-holders').style.width = boxW + 'px'; |
459 } | 439 } |
460 | 440 |
461 function buttonSubmitClick() | 441 function buttonSubmitClick() { |
462 { | 442 var checks = []; |
463 var checks = []; | 443 checks = checks.concat(testState.currentStateMap.interfaces[0].options); |
464 checks = checks.concat(testState.currentStateMap.interfaces[0].options); | 444 checks = checks.concat(specification.interfaces.options); |
465 checks = checks.concat(specification.interfaces.options); | 445 var canContinue = true; |
466 var canContinue = true; | 446 |
467 | 447 for (var i = 0; i < checks.length; i++) { |
468 for (var i=0; i<checks.length; i++) { | 448 if (checks[i].type == 'check') { |
469 if (checks[i].type == 'check') | 449 switch (checks[i].name) { |
470 { | 450 case 'fragmentPlayed': |
471 switch(checks[i].name) { | 451 // Check if all fragments have been played |
472 case 'fragmentPlayed': | 452 var checkState = interfaceContext.checkAllPlayed(); |
473 // Check if all fragments have been played | 453 if (checkState == false) { |
474 var checkState = interfaceContext.checkAllPlayed(); | 454 canContinue = false; |
475 if (checkState == false) {canContinue = false;} | 455 } |
476 break; | 456 break; |
477 case 'fragmentFullPlayback': | 457 case 'fragmentFullPlayback': |
478 // Check all fragments have been played to their full length | 458 // Check all fragments have been played to their full length |
479 var checkState = interfaceContext.checkFragmentsFullyPlayed(); | 459 var checkState = interfaceContext.checkFragmentsFullyPlayed(); |
480 if (checkState == false) {canContinue = false;} | 460 if (checkState == false) { |
481 break; | 461 canContinue = false; |
482 case 'fragmentMoved': | 462 } |
483 // Check all fragment sliders have been moved. | 463 break; |
484 var checkState = interfaceContext.checkAllMoved(); | 464 case 'fragmentMoved': |
485 if (checkState == false) {canContinue = false;} | 465 // Check all fragment sliders have been moved. |
486 break; | 466 var checkState = interfaceContext.checkAllMoved(); |
487 case 'fragmentComments': | 467 if (checkState == false) { |
488 // Check all fragment sliders have been moved. | 468 canContinue = false; |
489 var checkState = interfaceContext.checkAllCommented(); | 469 } |
490 if (checkState == false) {canContinue = false;} | 470 break; |
491 break; | 471 case 'fragmentComments': |
492 case 'scalerange': | 472 // Check all fragment sliders have been moved. |
493 // Check the scale has been used effectively | 473 var checkState = interfaceContext.checkAllCommented(); |
494 var checkState = interfaceContext.checkScaleRange(checks[i].min,checks[i].max); | 474 if (checkState == false) { |
495 if (checkState == false) {canContinue = false;} | 475 canContinue = false; |
496 break; | 476 } |
497 default: | 477 break; |
498 console.log("WARNING - Check option "+checks[i].check+" is not supported on this interface"); | 478 case 'scalerange': |
499 break; | 479 // Check the scale has been used effectively |
500 } | 480 var checkState = interfaceContext.checkScaleRange(checks[i].min, checks[i].max); |
501 | 481 if (checkState == false) { |
502 } | 482 canContinue = false; |
503 if (!canContinue) {break;} | 483 } |
504 } | 484 break; |
505 if (canContinue) | 485 default: |
506 { | 486 console.log("WARNING - Check option " + checks[i].check + " is not supported on this interface"); |
507 if (audioEngineContext.status == 1) { | 487 break; |
508 var playback = document.getElementById('playback-button'); | 488 } |
509 playback.click(); | 489 |
510 // This function is called when the submit button is clicked. Will check for any further tests to perform, or any post-test options | 490 } |
511 } else | 491 if (!canContinue) { |
512 { | 492 break; |
513 if (audioEngineContext.timer.testStarted == false) | 493 } |
514 { | 494 } |
515 interfaceContext.lightbox.post("Warning",'You have not started the test! Please listen to a sample to begin the test!'); | 495 if (canContinue) { |
516 return; | 496 if (audioEngineContext.status == 1) { |
517 } | 497 var playback = document.getElementById('playback-button'); |
518 } | 498 playback.click(); |
519 testState.advanceState(); | 499 // This function is called when the submit button is clicked. Will check for any further tests to perform, or any post-test options |
520 } | 500 } else { |
501 if (audioEngineContext.timer.testStarted == false) { | |
502 interfaceContext.lightbox.post("Warning", 'You have not started the test! Please listen to a sample to begin the test!'); | |
503 return; | |
504 } | |
505 } | |
506 testState.advanceState(); | |
507 } | |
521 } | 508 } |
522 | 509 |
523 function pageXMLSave(store, pageSpecification) | 510 function pageXMLSave(store, pageSpecification) { |
524 { | 511 // MANDATORY |
525 // MANDATORY | 512 // Saves a specific test page |
526 // Saves a specific test page | 513 // You can use this space to add any extra nodes to your XML <audioHolder> saves |
527 // You can use this space to add any extra nodes to your XML <audioHolder> saves | 514 // Get the current <page> information in store (remember to appendChild your data to it) |
528 // Get the current <page> information in store (remember to appendChild your data to it) | 515 // pageSpecification is the current page node configuration |
529 // pageSpecification is the current page node configuration | 516 // To create new XML nodes, use storage.document.createElement(); |
530 // To create new XML nodes, use storage.document.createElement(); | |
531 } | 517 } |