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