Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(201)

Side by Side Diff: experimental/webtry/res/js/webtry.js

Issue 688713002: delete webtry from main skia repo; it's been moved to buildbots (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: Created 6 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « experimental/webtry/res/js/polyfill.js ('k') | experimental/webtry/res/webtry/config.rb » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 /**
2 * Common JS that talks XHR back to the server and runs the code and receives
3 * the results.
4 */
5
6
7 /**
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
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
12 * running on a workspace page.
13 *
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
16 * that are included in this workspace. That variable is used to
17 * populate the history list.
18 */
19 (function() {
20 function onLoad() {
21 var run = document.getElementById('run');
22 var permalink = document.getElementById('permalink');
23 var embed = document.getElementById('embed');
24 var embedButton = document.getElementById('embedButton');
25 var code = document.getElementById('code');
26 var output = document.getElementById('output');
27 var outputWrapper = document.getElementById('output-wrapper');
28 var gpu = document.getElementById('use-gpu');
29 var raster = document.getElementById('use-raster');
30 var pdf = document.getElementById('use-pdf');
31 var rasterOutput = document.getElementById('raster-output');
32 var rasterImg = document.getElementById('raster-img');
33 var gpuOutput = document.getElementById('gpu-output');
34 var gpuImg = document.getElementById('gpu-img');
35 var imageWidth = document.getElementById('image-width');
36 var imageHeight = document.getElementById('image-height');
37 var tryHistory = document.getElementById('tryHistory');
38 var parser = new DOMParser();
39 var tryTemplate = document.getElementById('tryTemplate');
40 var sourcesTemplate = document.getElementById('sourcesTemplate');
41
42 var enableSource = document.getElementById('enableSource');
43 var selectedSource = document.getElementById('selectedSource');
44 var sourceCode = document.getElementById('sourceCode');
45 var chooseSource = document.getElementById('chooseSource');
46 var chooseList = document.getElementById('chooseList');
47
48 // Id of the source image to use, 0 if no source image is used.
49 var sourceId = 0;
50
51 sourceId = parseInt(enableSource.getAttribute('data-id'));
52 if (sourceId) {
53 sourceSelectByID(sourceId);
54 }
55
56 function setIFrameURL() {
57 var url = document.URL;
58 url = url.replace('/c/', '/iframe/');
59 embed.value = '<iframe src="' + url + '" width="740" height="550" style= "border: solid #00a 5px; border-radius: 5px;"/>'
60 }
61
62 function beginWait() {
63 document.body.classList.add('waiting');
64 run.disabled = true;
65 }
66
67
68 function endWait() {
69 document.body.classList.remove('waiting');
70 run.disabled = false;
71 }
72
73
74 function sourceSelectByID(id) {
75 sourceId = id;
76 if (id > 0) {
77 enableSource.checked = true;
78 selectedSource.innerHTML = '<img with=64 height=64 src="/i/image-'+sou rceId+'.png" />';
79 selectedSource.classList.add('show');
80 sourceCode.classList.add('show');
81 chooseSource.classList.remove('show');
82 } else {
83 enableSource.checked = false;
84 selectedSource.classList.remove('show');
85 sourceCode.classList.remove('show');
86 }
87 }
88
89
90 /**
91 * A selection has been made in the choiceList.
92 */
93 function sourceSelect() {
94 sourceSelectByID(parseInt(this.getAttribute('data-id')));
95 }
96
97
98 /**
99 * Callback when the loading of the image sources is complete.
100 *
101 * Fills in the list of images from the data returned.
102 */
103 function sourcesComplete(e) {
104 endWait();
105 // The response is JSON of the form:
106 // [
107 // {"id": 1},
108 // {"id": 3},
109 // ...
110 // ]
111 body = JSON.parse(e.target.response);
112 // Clear out the old list if present.
113 while (chooseList.firstChild) {
114 chooseList.removeChild(chooseList.firstChild);
115 }
116 body.forEach(function(source) {
117 var id = 'i'+source.id;
118 var imgsrc = '/i/image-'+source.id+'.png';
119 var clone = sourcesTemplate.content.cloneNode(true);
120 clone.querySelector('img').src = imgsrc;
121 clone.querySelector('button').setAttribute('id', id);
122 clone.querySelector('button').setAttribute('data-id', source.id);
123 chooseList.insertBefore(clone, chooseList.firstChild);
124 chooseList.querySelector('#'+id).addEventListener('click', sourceSelect , true);
125 });
126 chooseSource.classList.add('show');
127 }
128
129
130 /**
131 * Toggle the use of a source image, or select a new source image.
132 *
133 * If enabling source images then load the list of available images via
134 * XHR.
135 */
136 function sourceClick(e) {
137 selectedSource.classList.remove('show');
138 sourceCode.classList.remove('show');
139 if (enableSource.checked) {
140 beginWait();
141 var req = new XMLHttpRequest();
142 req.addEventListener('load', sourcesComplete);
143 req.addEventListener('error', xhrError);
144 req.overrideMimeType('application/json');
145 req.open('GET', '/sources/', true);
146 req.send();
147 } else {
148 sourceId = 0;
149 chooseSource.classList.remove('show');
150 }
151 }
152
153 enableSource.addEventListener('click', sourceClick, true);
154 selectedSource.addEventListener('click', sourceClick, true);
155
156 function configChange(e) {
157 if (!(gpu.checked || raster.checked || pdf.checked)) {
158 run.disabled = true;
159 run.innerHTML = "Choose a configuration"
160 } else {
161 run.disabled = false;
162 run.innerHTML = "Run"
163 }
164 }
165
166 gpu.addEventListener('change', configChange);
167 raster.addEventListener('change', configChange);
168 pdf.addEventListener('change', configChange);
169
170
171 var editor = CodeMirror.fromTextArea(code, {
172 theme: "default",
173 lineNumbers: true,
174 matchBrackets: true,
175 lineWrapping: true,
176 mode: "text/x-c++src",
177 indentUnit: 4,
178 });
179
180 // Match the initial textarea width, but leave the height alone
181 // The css will automatically resize the editor vertically.
182 editor.setSize(editor.defaultCharWidth() * code.cols,
183 null);
184
185 editor.on('beforeChange', function(instance, changeObj) {
186 var startLine = changeObj.from.line;
187 var endLine = changeObj.to.line;
188
189 for (var i = startLine ; i <= endLine ; i++) {
190 editor.removeLineClass( i, "wrap", "error" );
191 }
192 });
193
194 /**
195 * Callback when there's an XHR error.
196 * @param e The callback event.
197 */
198 function xhrError(e) {
199 endWait();
200 alert('Something bad happened: ' + e);
201 }
202
203 function clearOutput() {
204 output.textContent = "";
205 outputWrapper.style.display='none';
206 if (embed) {
207 embed.style.display='none';
208 }
209 }
210
211 /**
212 * Called when an image in the workspace history is clicked.
213 */
214 function historyClick() {
215 beginWait();
216 clearOutput();
217 var req = new XMLHttpRequest();
218 req.addEventListener('load', historyComplete);
219 req.addEventListener('error', xhrError);
220 req.overrideMimeType('application/json');
221 req.open('GET', this.getAttribute('data-try'), true);
222 req.send();
223 }
224
225
226 /**
227 * Callback for when the XHR kicked off in historyClick() returns.
228 */
229 function historyComplete(e) {
230 // The response is JSON of the form:
231 // {
232 // "hash": "unique id for a try",
233 // "code": "source code for try"
234 // }
235 endWait();
236 body = JSON.parse(e.target.response);
237 code.value = body.code;
238 editor.setValue(body.code);
239 rasterImg.src = '/i/'+body.hash+'_raster.png';
240 gpuImg.src = '/i/'+body.hash+'_gpu.png';
241 imageWidth.value = body.width;
242 imageHeight.value = body.height;
243 gpu.checked = body.gpu;
244 sourceSelectByID(body.source);
245 if (permalink) {
246 permalink.href = '/c/' + body.hash;
247 permalink.style.display='inline-block';
248 }
249 }
250
251
252 /**
253 * Add the given try image to the history of a workspace.
254 */
255 function addToHistory(hash, imgUrl) {
256 var clone = tryTemplate.content.cloneNode(true);
257 clone.querySelector('img').src = imgUrl;
258 clone.querySelector('.tries').setAttribute('data-try', '/json/' + hash);
259 tryHistory.insertBefore(clone, tryHistory.firstChild);
260 tryHistory.querySelector('.tries').addEventListener('click', historyClic k, true);
261 }
262
263 /**
264 * Callback for when the user clicks on a compile error message
265 *
266 */
267
268 function errorClick() {
269 var line = this.getAttribute('data-line');
270 var col = this.getAttribute('data-col');
271
272 editor.setCursor(line-1,col-1);
273 editor.focus();
274 }
275
276
277 /**
278 * Callback for when the XHR returns after attempting to run the code.
279 * @param e The callback event.
280 */
281 function codeComplete(e) {
282 // The response is JSON of the form:
283 // {
284 // "message": "you had an error...",
285 // "img": "<base64 encoded image but only on success>"
286 // }
287 //
288 // The img is optional and only appears if there is a valid
289 // image to display.
290 endWait();
291 body = JSON.parse(e.target.response);
292 if (null != body.compileErrors && body.compileErrors.length) {
293 html = "";
294 for (i = 0 ; i < body.compileErrors.length ; i++) {
295 compileError = body.compileErrors[i];
296
297 err = document.createElement("div");
298 err.className = "compile-error";
299
300 loc = document.createElement("span");
301 loc.className = "error-location";
302 loc.innerHTML = "Line " + compileError.line + ", col " + compileErro r.column + ": ";
303
304 errorMessage = document.createElement("span");
305 errorMessage.className = "error-mesage";
306 errorMessage.innerHTML = compileError.error;
307
308 err.appendChild(loc);
309 err.appendChild(errorMessage);
310
311 err.setAttribute('data-line', compileError.line);
312 err.setAttribute('data-col', compileError.column);
313
314 output.appendChild(err);
315
316 err.addEventListener('click', errorClick);
317
318 editor.addLineClass( parseInt( compileError.line ) - 1, "wrap", "err or" );
319 }
320 outputWrapper.style.display = 'block';
321 } else {
322 output.textContent = body.message;
323 if (body.message) {
324 outputWrapper.style.display = 'block';
325 }
326 }
327 if (body.hasOwnProperty('rasterImg') && body.rasterImg != "") {
328 rasterImg.src = 'data:image/png;base64,' + body.rasterImg;
329 rasterOutput.style.display = "inline-block";
330 } else {
331 rasterOutput.style.display = "none";
332 rasterImg.src = '';
333 }
334 if (body.hasOwnProperty('gpuImg') && body.gpuImg != "") {
335 gpuImg.src = 'data:image/png;base64,' + body.gpuImg;
336 gpuOutput.style.display = "inline-block";
337 } else {
338 gpuImg.src = '';
339 gpuOutput.style.display = "none";
340 }
341 // Add the image to the history if we are on a workspace page.
342 if (tryHistory) {
343 addToHistory(body.hash, 'data:image/png;base64,' + body.rasterImg);
344 } else {
345 window.history.pushState(null, null, '/c/' + body.hash);
346 }
347 if (permalink) {
348 permalink.href = '/c/' + body.hash;
349 permalink.style.display = 'inline-block';
350 }
351 if (embed) {
352 setIFrameURL();
353 }
354 if (embedButton) {
355 embedButton.style.display = 'inline-block';
356 }
357 }
358
359 function onSubmitCode() {
360 beginWait();
361 clearOutput();
362 var req = new XMLHttpRequest();
363 req.addEventListener('load', codeComplete);
364 req.addEventListener('error', xhrError);
365 req.overrideMimeType('application/json');
366 req.open('POST', '/', true);
367 req.setRequestHeader('content-type', 'application/json');
368 req.send(JSON.stringify({
369 'code': editor.getValue(),
370 'width': parseInt(imageWidth.value),
371 'height': parseInt(imageHeight.value),
372 'name': workspaceName,
373 'source': sourceId,
374 'gpu': gpu.checked,
375 'raster': raster.checked,
376 'pdf': pdf.checked
377 }));
378 }
379 run.addEventListener('click', onSubmitCode);
380
381
382 function onEmbedClick() {
383 embed.style.display='inline';
384 }
385
386 if (embedButton) {
387 embedButton.addEventListener('click', onEmbedClick);
388 }
389
390 setIFrameURL();
391
392 // Add the images to the history if we are on a workspace page.
393 if (tryHistory && history_) {
394 for (var i=0; i<history_.length; i++) {
395 addToHistory(history_[i].hash, '/i/'+history_[i].hash+'.png');
396 }
397 }
398 }
399
400 // If loaded via HTML Imports then DOMContentLoaded will be long done.
401 if (document.readyState != "loading") {
402 onLoad();
403 } else {
404 this.addEventListener('load', onLoad);
405 }
406
407 })();
408
409 // TODO (humper) -- move the following functions out of the global
410 // namespace as part of a web-components based fiddle frontend rewrite.
411
412 function collectionHas(a, b) { //helper function (see below)
413 for(var i = 0, len = a.length; i < len; i ++) {
414 if(a[i] == b) return true;
415 }
416 return false;
417 }
418 function findParentBySelector(elm, selector) {
419 var all = document.querySelectorAll(selector);
420 var cur = elm.parentNode;
421 while(cur && !collectionHas(all, cur)) { //keep going up until you find a ma tch
422 cur = cur.parentNode; //go up
423 }
424 return cur; //will return null if not found
425 }
426
427 function onLoadImage(img) {
428 var wrapper = findParentBySelector(img, ".image-wrapper");
429 wrapper.style.display = "inline-block";
430 }
OLDNEW
« no previous file with comments | « experimental/webtry/res/js/polyfill.js ('k') | experimental/webtry/res/webtry/config.rb » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698