OLD | NEW |
1 /** | 1 /** |
2 * Common JS that talks XHR back to the server and runs the code and receives | 2 * Common JS that talks XHR back to the server and runs the code and receives |
3 * the results. | 3 * the results. |
4 */ | 4 */ |
5 | 5 |
6 | 6 |
7 /** | 7 /** |
8 * All the functionality is wrapped up in this anonymous closure, but we need | 8 * All the functionality is wrapped up in this anonymous closure, but we need |
9 * to be told if we are on the workspace page or a normal try page, so the | 9 * to be told if we are on the workspace page or a normal try page, so the |
10 * workspaceName is passed into the closure, it must be set in the global | 10 * workspaceName is passed into the closure, it must be set in the global |
11 * namespace. If workspaceName is the empty string then we know we aren't | 11 * namespace. If workspaceName is the empty string then we know we aren't |
12 * running on a workspace page. | 12 * running on a workspace page. |
13 * | 13 * |
14 * If we are on a workspace page we also look for a 'history_' | 14 * If we are on a workspace page we also look for a 'history_' |
15 * variable in the global namespace which contains the list of tries | 15 * variable in the global namespace which contains the list of tries |
16 * that are included in this workspace. That variable is used to | 16 * that are included in this workspace. That variable is used to |
17 * populate the history list. | 17 * populate the history list. |
18 */ | 18 */ |
19 (function() { | 19 (function() { |
20 function onLoad() { | 20 function onLoad() { |
21 var run = document.getElementById('run'); | 21 var run = document.getElementById('run'); |
22 var permalink = document.getElementById('permalink'); | 22 var permalink = document.getElementById('permalink'); |
23 var embed = document.getElementById('embed'); | 23 var embed = document.getElementById('embed'); |
24 var embedButton = document.getElementById('embedButton'); | 24 var embedButton = document.getElementById('embedButton'); |
25 var code = document.getElementById('code'); | 25 var code = document.getElementById('code'); |
26 var output = document.getElementById('output'); | 26 var output = document.getElementById('output'); |
27 var stdout = document.getElementById('stdout'); | 27 var outputWrapper = document.getElementById('output-wrapper'); |
28 var gpu = document.getElementById('use-gpu'); | 28 var gpu = document.getElementById('use-gpu'); |
29 var img = document.getElementById('img'); | 29 var img = document.getElementById('img'); |
30 var imageWidth = document.getElementById('image-width'); | 30 var imageWidth = document.getElementById('image-width'); |
31 var imageHeight = document.getElementById('image-height'); | 31 var imageHeight = document.getElementById('image-height'); |
32 var tryHistory = document.getElementById('tryHistory'); | 32 var tryHistory = document.getElementById('tryHistory'); |
33 var parser = new DOMParser(); | 33 var parser = new DOMParser(); |
34 var tryTemplate = document.getElementById('tryTemplate'); | 34 var tryTemplate = document.getElementById('tryTemplate'); |
35 var sourcesTemplate = document.getElementById('sourcesTemplate'); | 35 var sourcesTemplate = document.getElementById('sourcesTemplate'); |
36 | 36 |
37 var enableSource = document.getElementById('enableSource'); | 37 var enableSource = document.getElementById('enableSource'); |
(...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
156 lineWrapping: true, | 156 lineWrapping: true, |
157 mode: "text/x-c++src", | 157 mode: "text/x-c++src", |
158 indentUnit: 4, | 158 indentUnit: 4, |
159 }); | 159 }); |
160 | 160 |
161 // Match the initial textarea width, but leave the height alone | 161 // Match the initial textarea width, but leave the height alone |
162 // The css will automatically resize the editor vertically. | 162 // The css will automatically resize the editor vertically. |
163 editor.setSize(editor.defaultCharWidth() * code.cols, | 163 editor.setSize(editor.defaultCharWidth() * code.cols, |
164 null); | 164 null); |
165 | 165 |
| 166 editor.on('beforeChange', function(instance, changeObj) { |
| 167 var startLine = changeObj.from.line; |
| 168 var endLine = changeObj.to.line; |
| 169 |
| 170 for (var i = startLine ; i <= endLine ; i++) { |
| 171 editor.removeLineClass( i, "wrap", "error" ); |
| 172 } |
| 173 }); |
166 | 174 |
167 /** | 175 /** |
168 * Callback when there's an XHR error. | 176 * Callback when there's an XHR error. |
169 * @param e The callback event. | 177 * @param e The callback event. |
170 */ | 178 */ |
171 function xhrError(e) { | 179 function xhrError(e) { |
172 endWait(); | 180 endWait(); |
173 alert('Something bad happened: ' + e); | 181 alert('Something bad happened: ' + e); |
174 } | 182 } |
175 | 183 |
176 function clearOutput() { | 184 function clearOutput() { |
177 output.textContent = ""; | 185 output.textContent = ""; |
178 output.style.display='none'; | 186 outputWrapper.style.display='none'; |
179 if (stdout) { | |
180 stdout.textContent = ""; | |
181 stdout.style.display='none'; | |
182 } | |
183 if (embed) { | 187 if (embed) { |
184 embed.style.display='none'; | 188 embed.style.display='none'; |
185 } | 189 } |
186 } | 190 } |
187 | 191 |
188 /** | 192 /** |
189 * Called when an image in the workspace history is clicked. | 193 * Called when an image in the workspace history is clicked. |
190 */ | 194 */ |
191 function historyClick() { | 195 function historyClick() { |
192 beginWait(); | 196 beginWait(); |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
229 * Add the given try image to the history of a workspace. | 233 * Add the given try image to the history of a workspace. |
230 */ | 234 */ |
231 function addToHistory(hash, imgUrl) { | 235 function addToHistory(hash, imgUrl) { |
232 var clone = tryTemplate.content.cloneNode(true); | 236 var clone = tryTemplate.content.cloneNode(true); |
233 clone.querySelector('img').src = imgUrl; | 237 clone.querySelector('img').src = imgUrl; |
234 clone.querySelector('.tries').setAttribute('data-try', '/json/' + hash); | 238 clone.querySelector('.tries').setAttribute('data-try', '/json/' + hash); |
235 tryHistory.insertBefore(clone, tryHistory.firstChild); | 239 tryHistory.insertBefore(clone, tryHistory.firstChild); |
236 tryHistory.querySelector('.tries').addEventListener('click', historyClic
k, true); | 240 tryHistory.querySelector('.tries').addEventListener('click', historyClic
k, true); |
237 } | 241 } |
238 | 242 |
| 243 /** |
| 244 * Callback for when the user clicks on a compile error message |
| 245 * |
| 246 */ |
| 247 |
| 248 function errorClick() { |
| 249 var line = this.getAttribute('data-line'); |
| 250 var col = this.getAttribute('data-col'); |
| 251 |
| 252 editor.setCursor(line-1,col-1); |
| 253 editor.focus(); |
| 254 } |
| 255 |
239 | 256 |
240 /** | 257 /** |
241 * Callback for when the XHR returns after attempting to run the code. | 258 * Callback for when the XHR returns after attempting to run the code. |
242 * @param e The callback event. | 259 * @param e The callback event. |
243 */ | 260 */ |
244 function codeComplete(e) { | 261 function codeComplete(e) { |
245 // The response is JSON of the form: | 262 // The response is JSON of the form: |
246 // { | 263 // { |
247 // "message": "you had an error...", | 264 // "message": "you had an error...", |
248 // "img": "<base64 encoded image but only on success>" | 265 // "img": "<base64 encoded image but only on success>" |
249 // } | 266 // } |
250 // | 267 // |
251 // The img is optional and only appears if there is a valid | 268 // The img is optional and only appears if there is a valid |
252 // image to display. | 269 // image to display. |
253 endWait(); | 270 endWait(); |
254 body = JSON.parse(e.target.response); | 271 body = JSON.parse(e.target.response); |
255 output.textContent = body.message; | 272 if (body.compileErrors.length) { |
256 if (body.message) { | 273 html = ""; |
257 output.style.display = 'block'; | 274 for (i = 0 ; i < body.compileErrors.length ; i++) { |
258 } | 275 compileError = body.compileErrors[i]; |
259 if (stdout) { | 276 |
260 stdout.textContent = body.stdout; | 277 err = document.createElement("div"); |
261 if (body.stdout) { | 278 err.className = "compile-error"; |
262 stdout.style.display = 'block'; | 279 |
| 280 loc = document.createElement("span"); |
| 281 loc.className = "error-location"; |
| 282 loc.innerHTML = "Line " + compileError.line + ", col " + compileErro
r.column + ": "; |
| 283 |
| 284 errorMessage = document.createElement("span"); |
| 285 errorMessage.className = "error-mesage"; |
| 286 errorMessage.innerHTML = compileError.error; |
| 287 |
| 288 err.appendChild(loc); |
| 289 err.appendChild(errorMessage); |
| 290 |
| 291 err.setAttribute('data-line', compileError.line); |
| 292 err.setAttribute('data-col', compileError.column); |
| 293 |
| 294 output.appendChild(err); |
| 295 |
| 296 err.addEventListener('click', errorClick); |
| 297 |
| 298 editor.addLineClass( parseInt( compileError.line ) - 1, "wrap", "err
or" ); |
| 299 } |
| 300 outputWrapper.style.display = 'block'; |
| 301 } else { |
| 302 output.textContent = body.message; |
| 303 if (body.message) { |
| 304 outputWrapper.style.display = 'block'; |
263 } | 305 } |
264 } | 306 } |
265 if (body.hasOwnProperty('img')) { | 307 if (body.hasOwnProperty('img')) { |
266 img.src = 'data:image/png;base64,' + body.img; | 308 img.src = 'data:image/png;base64,' + body.img; |
267 } else { | 309 } else { |
268 img.src = ''; | 310 img.src = ''; |
269 } | 311 } |
270 // Add the image to the history if we are on a workspace page. | 312 // Add the image to the history if we are on a workspace page. |
271 if (tryHistory) { | 313 if (tryHistory) { |
272 addToHistory(body.hash, 'data:image/png;base64,' + body.img); | 314 addToHistory(body.hash, 'data:image/png;base64,' + body.img); |
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
326 } | 368 } |
327 | 369 |
328 // If loaded via HTML Imports then DOMContentLoaded will be long done. | 370 // If loaded via HTML Imports then DOMContentLoaded will be long done. |
329 if (document.readyState != "loading") { | 371 if (document.readyState != "loading") { |
330 onLoad(); | 372 onLoad(); |
331 } else { | 373 } else { |
332 this.addEventListener('load', onLoad); | 374 this.addEventListener('load', onLoad); |
333 } | 375 } |
334 | 376 |
335 })(); | 377 })(); |
OLD | NEW |