| 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 |