| var YosysJS = new function() { | |
| this.script_element = document.currentScript; | |
| this.viz_element = undefined; | |
| this.viz_ready = true; | |
| this.url_prefix = this.script_element.src.replace(/[^/]+$/, '') | |
| this.load_viz = function() { | |
| if (this.viz_element) | |
| return; | |
| this.viz_element = document.createElement('iframe') | |
| this.viz_element.style.display = 'none' | |
| document.body.appendChild(this.viz_element); | |
| this.viz_element.contentWindow.document.open(); | |
| this.viz_element.contentWindow.document.write('<script type="text/javascript" onload="viz_ready = true;" src="' + this.url_prefix + 'viz.js"></' + 'script>'); | |
| this.viz_element.contentWindow.document.close(); | |
| var that = this; | |
| function check_viz_ready() { | |
| if (that.viz_element.contentWindow.viz_ready) { | |
| console.log("YosysJS: Successfully loaded Viz."); | |
| that.viz_ready = true; | |
| } else | |
| window.setTimeout(check_viz_ready, 100); | |
| } | |
| this.viz_ready = false; | |
| window.setTimeout(check_viz_ready, 100); | |
| } | |
| this.dot_to_svg = function(dot_text) { | |
| return this.viz_element.contentWindow.Viz(dot_text, "svg"); | |
| } | |
| this.dot_into_svg = function(dot_text, svg_element) { | |
| if (typeof(svg_element) == 'string' && svg_element != "") | |
| svg_element = document.getElementById(svg_element); | |
| svg_element.innerHTML = this.dot_to_svg(dot_text); | |
| c = svg_element.firstChild; | |
| while (c) { | |
| if (c.tagName == 'svg') { | |
| while (c.firstChild) | |
| svg_element.appendChild(c.firstChild); | |
| svg_element.setAttribute('viewBox', c.getAttribute('viewBox')); | |
| // svg_element.removeChild(c); | |
| break; | |
| } | |
| c = c.nextSibling; | |
| } | |
| } | |
| this.create = function(reference_element, on_ready) { | |
| var ys = new Object(); | |
| ys.YosysJS = this; | |
| ys.init_script = ""; | |
| ys.ready = false; | |
| ys.verbose = false; | |
| ys.logprint = false; | |
| ys.echo = false; | |
| ys.errmsg = ""; | |
| if (typeof(reference_element) == 'string' && reference_element != "") | |
| reference_element = document.getElementById(reference_element); | |
| if (reference_element) { | |
| if (reference_element.tagName == 'textarea') | |
| ys.init_script = reference_element.value; | |
| if (reference_element.tagName == 'iframe') { | |
| ys.iframe_element = reference_element; | |
| } else { | |
| ys.iframe_element = document.createElement('iframe'); | |
| ys.iframe_element.id = reference_element.id; | |
| for (i in reference_element.style) | |
| ys.iframe_element.style[i] = reference_element.style[i]; | |
| reference_element.parentNode.insertBefore(ys.iframe_element, reference_element); | |
| reference_element.parentNode.removeChild(reference_element); | |
| } | |
| } else { | |
| ys.iframe_element = document.createElement('iframe'); | |
| ys.iframe_element.style.display = 'none'; | |
| document.body.appendChild(ys.iframe_element); | |
| } | |
| ys.print_buffer = ""; | |
| ys.last_line_empty = false; | |
| ys.got_normal_log_message = false; | |
| ys.window = ys.iframe_element.contentWindow; | |
| var doc = ys.window.document; | |
| var mod = ys.window.Module = { | |
| print: function(text) { | |
| if (typeof(text) == 'number') | |
| return; | |
| ys.print_buffer += text + "\n"; | |
| ys.got_normal_log_message = true; | |
| if (ys.logprint) | |
| console.log(text); | |
| if (ys.verbose) { | |
| ys.last_line_empty = text == ""; | |
| if (text == "") { | |
| span = doc.createElement('br'); | |
| } else { | |
| span = doc.createElement('span'); | |
| span.textContent = text + "\n"; | |
| span.style.fontFamily = 'monospace'; | |
| span.style.whiteSpace = 'pre'; | |
| } | |
| doc.firstChild.appendChild(span); | |
| if (doc.body) | |
| ys.window.scrollTo(0, doc.body.scrollHeight); | |
| else | |
| ys.window.scrollBy(0, 100); | |
| } | |
| ys.ready = true; | |
| }, | |
| printErr: function(text) { | |
| if (typeof(text) == 'number') | |
| return; | |
| if (ys.logprint) | |
| console.log(text); | |
| if (ys.got_normal_log_message) { | |
| ys.print_buffer += text + "\n"; | |
| ys.last_line_empty = text == ""; | |
| if (text == "") { | |
| span = doc.createElement('br'); | |
| } else { | |
| span = doc.createElement('span'); | |
| span.textContent = text + "\n"; | |
| span.style.fontFamily = 'monospace'; | |
| span.style.whiteSpace = 'pre'; | |
| span.style.color = 'red'; | |
| } | |
| doc.firstChild.appendChild(span); | |
| if (doc.body) | |
| ys.window.scrollTo(0, doc.body.scrollHeight); | |
| else | |
| ys.window.scrollBy(0, 100); | |
| } else | |
| if (!ys.logprint) | |
| console.log(text); | |
| }, | |
| }; | |
| ys.write = function(text) { | |
| ys.print_buffer += text + "\n"; | |
| ys.last_line_empty = text == ""; | |
| span = doc.createElement('span'); | |
| span.textContent = text + "\n"; | |
| span.style.fontFamily = 'monospace'; | |
| span.style.whiteSpace = 'pre'; | |
| doc.firstChild.appendChild(span); | |
| if (doc.body) | |
| ys.window.scrollTo(0, doc.body.scrollHeight); | |
| else | |
| ys.window.scrollBy(0, 100); | |
| } | |
| ys.prompt = function() { | |
| return mod.ccall('prompt', 'string', [], []) | |
| } | |
| ys.run = function(cmd) { | |
| ys.print_buffer = ""; | |
| if (ys.echo) { | |
| if (!ys.last_line_empty) | |
| ys.write(""); | |
| ys.write(ys.prompt() + cmd); | |
| } | |
| try { | |
| mod.ccall('run', '', ['string'], [cmd]); | |
| } catch (e) { | |
| ys.errmsg = mod.ccall('errmsg', 'string', [], []); | |
| } | |
| return ys.print_buffer; | |
| } | |
| ys.read_file = function(filename) { | |
| try { | |
| return ys.window.FS.readFile(filename, {encoding: 'utf8'}); | |
| } catch (e) { | |
| return ""; | |
| } | |
| } | |
| ys.write_file = function(filename, text) { | |
| return ys.window.FS.writeFile(filename, text, {encoding: 'utf8'}); | |
| } | |
| ys.read_dir = function(dirname) { | |
| return ys.window.FS.readdir(dirname); | |
| } | |
| ys.remove_file = function(filename) { | |
| try { | |
| ys.window.FS.unlink(filename); | |
| } catch (e) { } | |
| } | |
| doc.open(); | |
| doc.write('<script type="text/javascript" src="' + this.url_prefix + 'yosys.js"></' + 'script>'); | |
| doc.close(); | |
| if (on_ready || ys.init_script) { | |
| function check_ready() { | |
| if (ys.ready && ys.YosysJS.viz_ready) { | |
| if (ys.init_script) { | |
| ys.write_file("/script.ys", ys.init_script); | |
| ys.run("script /script.ys"); | |
| } | |
| if (on_ready) | |
| on_ready(ys); | |
| } else | |
| window.setTimeout(check_ready, 100); | |
| } | |
| window.setTimeout(check_ready, 100); | |
| } | |
| return ys; | |
| } | |
| this.create_worker = function(on_ready) { | |
| var ys = new Object(); | |
| ys.YosysJS = this; | |
| ys.worker = new Worker(this.url_prefix + 'yosyswrk.js'); | |
| ys.callback_idx = 1; | |
| ys.callback_cache = {}; | |
| ys.errmsg = ""; | |
| ys.callback_cache[0] = on_ready; | |
| on_ready = null; | |
| ys.worker.onmessage = function(e) { | |
| var response = e.data[0]; | |
| var callback = ys.callback_cache[response.idx]; | |
| delete ys.callback_cache[response.idx]; | |
| if ("errmsg" in response) ys.errmsg = response.errmsg; | |
| if (callback) callback.apply(null, response.args); | |
| } | |
| ys.run = function(cmd, callback) { | |
| var request = { | |
| "idx": ys.callback_idx, | |
| "mode": "run", | |
| "cmd": cmd | |
| }; | |
| ys.callback_cache[ys.callback_idx++] = callback; | |
| ys.worker.postMessage([request]); | |
| } | |
| ys.read_file = function(filename, callback) { | |
| var request = { | |
| "idx": ys.callback_idx, | |
| "mode": "read_file", | |
| "filename": filename | |
| }; | |
| ys.callback_cache[ys.callback_idx++] = callback; | |
| ys.worker.postMessage([request]); | |
| } | |
| ys.write_file = function(filename, text, callback) { | |
| var request = { | |
| "idx": ys.callback_idx, | |
| "mode": "write_file", | |
| "filename": filename, | |
| "text": text | |
| }; | |
| ys.callback_cache[ys.callback_idx++] = callback; | |
| ys.worker.postMessage([request]); | |
| } | |
| ys.read_dir = function(dirname, callback) { | |
| var request = { | |
| "idx": ys.callback_idx, | |
| "mode": "read_dir", | |
| "dirname": dirname | |
| }; | |
| ys.callback_cache[ys.callback_idx++] = callback; | |
| ys.worker.postMessage([request]); | |
| } | |
| ys.remove_file = function(filename, callback) { | |
| var request = { | |
| "idx": ys.callback_idx, | |
| "mode": "remove_file", | |
| "filename": filename | |
| }; | |
| ys.callback_cache[ys.callback_idx++] = callback; | |
| ys.worker.postMessage([request]); | |
| } | |
| ys.verbose = function(value, callback) { | |
| var request = { | |
| "idx": ys.callback_idx, | |
| "mode": "verbose", | |
| "value": value | |
| }; | |
| ys.callback_cache[ys.callback_idx++] = callback; | |
| ys.worker.postMessage([request]); | |
| } | |
| return ys; | |
| } | |
| } |