Commit 7fe095a2 authored by Alex Beregszaszi's avatar Alex Beregszaszi

Remove DOS newlines

parent 632d604a
var Base64={_keyStr:"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=",encode:function(e){var t="";var n,r,i,s,o,u,a;var f=0;e=Base64._utf8_encode(e);while(f<e.length){n=e.charCodeAt(f++);r=e.charCodeAt(f++);i=e.charCodeAt(f++);s=n>>2;o=(n&3)<<4|r>>4;u=(r&15)<<2|i>>6;a=i&63;if(isNaN(r)){u=a=64}else if(isNaN(i)){a=64}t=t+this._keyStr.charAt(s)+this._keyStr.charAt(o)+this._keyStr.charAt(u)+this._keyStr.charAt(a)}return t},decode:function(e){var t="";var n,r,i;var s,o,u,a;var f=0;e=e.replace(/[^A-Za-z0-9\+\/\=]/g,"");while(f<e.length){s=this._keyStr.indexOf(e.charAt(f++));o=this._keyStr.indexOf(e.charAt(f++));u=this._keyStr.indexOf(e.charAt(f++));a=this._keyStr.indexOf(e.charAt(f++));n=s<<2|o>>4;r=(o&15)<<4|u>>2;i=(u&3)<<6|a;t=t+String.fromCharCode(n);if(u!=64){t=t+String.fromCharCode(r)}if(a!=64){t=t+String.fromCharCode(i)}}t=Base64._utf8_decode(t);return t},_utf8_encode:function(e){e=e.replace(/\r\n/g,"\n");var t="";for(var n=0;n<e.length;n++){var r=e.charCodeAt(n);if(r<128){t+=String.fromCharCode(r)}else if(r>127&&r<2048){t+=String.fromCharCode(r>>6|192);t+=String.fromCharCode(r&63|128)}else{t+=String.fromCharCode(r>>12|224);t+=String.fromCharCode(r>>6&63|128);t+=String.fromCharCode(r&63|128)}}return t},_utf8_decode:function(e){var t="";var n=0;var r=c1=c2=0;while(n<e.length){r=e.charCodeAt(n);if(r<128){t+=String.fromCharCode(r);n++}else if(r>191&&r<224){c2=e.charCodeAt(n+1);t+=String.fromCharCode((r&31)<<6|c2&63);n+=2}else{c2=e.charCodeAt(n+1);c3=e.charCodeAt(n+2);t+=String.fromCharCode((r&15)<<12|(c2&63)<<6|c3&63);n+=3}}return t}}; var Base64={_keyStr:"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=",encode:function(e){var t="";var n,r,i,s,o,u,a;var f=0;e=Base64._utf8_encode(e);while(f<e.length){n=e.charCodeAt(f++);r=e.charCodeAt(f++);i=e.charCodeAt(f++);s=n>>2;o=(n&3)<<4|r>>4;u=(r&15)<<2|i>>6;a=i&63;if(isNaN(r)){u=a=64}else if(isNaN(i)){a=64}t=t+this._keyStr.charAt(s)+this._keyStr.charAt(o)+this._keyStr.charAt(u)+this._keyStr.charAt(a)}return t},decode:function(e){var t="";var n,r,i;var s,o,u,a;var f=0;e=e.replace(/[^A-Za-z0-9\+\/\=]/g,"");while(f<e.length){s=this._keyStr.indexOf(e.charAt(f++));o=this._keyStr.indexOf(e.charAt(f++));u=this._keyStr.indexOf(e.charAt(f++));a=this._keyStr.indexOf(e.charAt(f++));n=s<<2|o>>4;r=(o&15)<<4|u>>2;i=(u&3)<<6|a;t=t+String.fromCharCode(n);if(u!=64){t=t+String.fromCharCode(r)}if(a!=64){t=t+String.fromCharCode(i)}}t=Base64._utf8_decode(t);return t},_utf8_encode:function(e){e=e.replace(/\r\n/g,"\n");var t="";for(var n=0;n<e.length;n++){var r=e.charCodeAt(n);if(r<128){t+=String.fromCharCode(r)}else if(r>127&&r<2048){t+=String.fromCharCode(r>>6|192);t+=String.fromCharCode(r&63|128)}else{t+=String.fromCharCode(r>>12|224);t+=String.fromCharCode(r>>6&63|128);t+=String.fromCharCode(r&63|128)}}return t},_utf8_decode:function(e){var t="";var n=0;var r=c1=c2=0;while(n<e.length){r=e.charCodeAt(n);if(r<128){t+=String.fromCharCode(r);n++}else if(r>191&&r<224){c2=e.charCodeAt(n+1);t+=String.fromCharCode((r&31)<<6|c2&63);n+=2}else{c2=e.charCodeAt(n+1);c3=e.charCodeAt(n+2);t+=String.fromCharCode((r&15)<<12|(c2&63)<<6|c3&63);n+=3}}return t}};
$(document).ready(function() { $(document).ready(function() {
// ------------------ query params (hash) ---------------- // ------------------ query params (hash) ----------------
...@@ -48,7 +48,7 @@ ...@@ -48,7 +48,7 @@
window.onhashchange = syncQueryParams; window.onhashchange = syncQueryParams;
syncQueryParams(); syncQueryParams();
// ------------------ gist load ---------------- // ------------------ gist load ----------------
function getGistId(str) { function getGistId(str) {
var idr = /[0-9A-Fa-f]{8,}/; var idr = /[0-9A-Fa-f]{8,}/;
...@@ -62,11 +62,11 @@ ...@@ -62,11 +62,11 @@
var gistId; var gistId;
if (queryParams['gist'] === '') { if (queryParams['gist'] === '') {
var str = prompt("Enter the URL or ID of the Gist you would like to load."); var str = prompt("Enter the URL or ID of the Gist you would like to load.");
if (str !== '') { if (str !== '') {
gistId = getGistId( str ); gistId = getGistId( str );
loadingFromGist = !!gistId; loadingFromGist = !!gistId;
} }
} else { } else {
gistId = queryParams['gist']; gistId = queryParams['gist'];
loadingFromGist = !!gistId; loadingFromGist = !!gistId;
} }
...@@ -74,179 +74,179 @@ ...@@ -74,179 +74,179 @@
url: 'https://api.github.com/gists/'+gistId, url: 'https://api.github.com/gists/'+gistId,
jsonp: 'callback', jsonp: 'callback',
dataType: 'jsonp', dataType: 'jsonp',
success: function(response){ success: function(response){
if (response.data) { if (response.data) {
for (var f in response.data.files) { for (var f in response.data.files) {
var key = fileKey(f); var key = fileKey(f);
var content = response.data.files[f].content; var content = response.data.files[f].content;
if (key in window.localStorage && window.localStorage[key] != content) { if (key in window.localStorage && window.localStorage[key] != content) {
var count = ''; var count = '';
var otherKey = key + count; var otherKey = key + count;
while ((key + count) in window.localStorage) count = count - 1; while ((key + count) in window.localStorage) count = count - 1;
window.localStorage[key + count] = window.localStorage[key]; window.localStorage[key + count] = window.localStorage[key];
} }
window.localStorage[key] = content; window.localStorage[key] = content;
} }
if (!response.data.files) { if (!response.data.files) {
alert( "Gist load error: " + response.data.message ) alert( "Gist load error: " + response.data.message )
} else { } else {
SOL_CACHE_FILE = fileKey(Object.keys(response.data.files)[0]); SOL_CACHE_FILE = fileKey(Object.keys(response.data.files)[0]);
updateFiles(); updateFiles();
} }
} }
} }
}); });
} }
// ----------------- storage -------------------- // ----------------- storage --------------------
function syncStorage() { function syncStorage() {
if (typeof chrome === 'undefined' || !chrome || !chrome.storage || !chrome.storage.sync) return; if (typeof chrome === 'undefined' || !chrome || !chrome.storage || !chrome.storage.sync) return;
var obj = {} var obj = {}
var done = false; var done = false;
var count = 0 var count = 0
var dont = 0; var dont = 0;
function check(key){ function check(key){
chrome.storage.sync.get( key, function(resp){ chrome.storage.sync.get( key, function(resp){
console.log("comparing to cloud", key, resp) console.log("comparing to cloud", key, resp)
if (typeof resp[key] != 'undefined' && obj[key] !== resp[key] && confirm("Overwrite '" + fileNameFromKey(key) + "'? Click Ok to overwrite local file with file from cloud. Cancel will push your local file to the cloud.")) { if (typeof resp[key] != 'undefined' && obj[key] !== resp[key] && confirm("Overwrite '" + fileNameFromKey(key) + "'? Click Ok to overwrite local file with file from cloud. Cancel will push your local file to the cloud.")) {
console.log("Overwriting", key ) console.log("Overwriting", key )
localStorage.setItem( key, resp[key] ); localStorage.setItem( key, resp[key] );
updateFiles(); updateFiles();
} else { } else {
console.log( "add to obj", obj, key) console.log( "add to obj", obj, key)
obj[key] = localStorage[key]; obj[key] = localStorage[key];
} }
done++ done++
if (done >= count) chrome.storage.sync.set( obj, function(){ if (done >= count) chrome.storage.sync.set( obj, function(){
console.log( "updated cloud files with: ", obj, this, arguments) console.log( "updated cloud files with: ", obj, this, arguments)
}) })
}) })
} }
for (var y in window.localStorage) { for (var y in window.localStorage) {
console.log("checking", y) console.log("checking", y)
obj[y] = window.localStorage.getItem(y); obj[y] = window.localStorage.getItem(y);
if (y.indexOf(SOL_CACHE_FILE_PREFIX) !== 0) continue; if (y.indexOf(SOL_CACHE_FILE_PREFIX) !== 0) continue;
count++; count++;
check(y) check(y)
} }
} }
window.syncStorage = syncStorage; window.syncStorage = syncStorage;
syncStorage() syncStorage()
// ----------------- editor ---------------------- // ----------------- editor ----------------------
var SOL_CACHE_FILE_PREFIX = 'sol-cache-file-'; var SOL_CACHE_FILE_PREFIX = 'sol-cache-file-';
var SOL_CACHE_UNTITLED = SOL_CACHE_FILE_PREFIX + 'Untitled'; var SOL_CACHE_UNTITLED = SOL_CACHE_FILE_PREFIX + 'Untitled';
var SOL_CACHE_FILE = null; var SOL_CACHE_FILE = null;
var editor = ace.edit("input"); var editor = ace.edit("input");
var sessions = {}; var sessions = {};
var Range = ace.require('ace/range').Range; var Range = ace.require('ace/range').Range;
var errMarkerId = null; var errMarkerId = null;
var untitledCount = ''; var untitledCount = '';
if (!getFiles().length || window.localStorage['sol-cache']) { if (!getFiles().length || window.localStorage['sol-cache']) {
if(loadingFromGist) return; if(loadingFromGist) return;
// Backwards-compatibility // Backwards-compatibility
while (window.localStorage[SOL_CACHE_UNTITLED + untitledCount]) while (window.localStorage[SOL_CACHE_UNTITLED + untitledCount])
untitledCount = (untitledCount - 0) + 1; untitledCount = (untitledCount - 0) + 1;
SOL_CACHE_FILE = SOL_CACHE_UNTITLED + untitledCount; SOL_CACHE_FILE = SOL_CACHE_UNTITLED + untitledCount;
window.localStorage[SOL_CACHE_FILE] = window.localStorage['sol-cache'] || BALLOT_EXAMPLE; window.localStorage[SOL_CACHE_FILE] = window.localStorage['sol-cache'] || BALLOT_EXAMPLE;
window.localStorage.removeItem('sol-cache'); window.localStorage.removeItem('sol-cache');
}
SOL_CACHE_FILE = getFiles()[0];
var files = getFiles();
for (var x in files) {
sessions[files[x]] = newEditorSession(files[x])
} }
editor.setSession( sessions[SOL_CACHE_FILE] ); SOL_CACHE_FILE = getFiles()[0];
editor.resize(true);
function newEditorSession(filekey) { var files = getFiles();
var s = new ace.EditSession(window.localStorage[filekey], "ace/mode/javascript") for (var x in files) {
s.setTabSize(4); sessions[files[x]] = newEditorSession(files[x])
s.setUseSoftTabs(true); }
sessions[filekey] = s;
return s; editor.setSession( sessions[SOL_CACHE_FILE] );
} editor.resize(true);
function newEditorSession(filekey) {
var s = new ace.EditSession(window.localStorage[filekey], "ace/mode/javascript")
// ----------------- tabbed menu ------------------- s.setTabSize(4);
s.setUseSoftTabs(true);
$('#options li').click(function(ev){ sessions[filekey] = s;
var $el = $(this); return s;
var match = /[a-z]+View/.exec( $el.get(0).className ); }
if (!match) return;
var cls = match[0];
if (!$el.hasClass('active')) {
$el.parent().find('li').removeClass('active'); // ----------------- tabbed menu -------------------
$('#optionViews').attr('class', '').addClass(cls);
$el.addClass('active'); $('#options li').click(function(ev){
} else { var $el = $(this);
$el.removeClass('active'); var match = /[a-z]+View/.exec( $el.get(0).className );
$('#optionViews').removeClass(cls); if (!match) return;
} var cls = match[0];
}); if (!$el.hasClass('active')) {
$el.parent().find('li').removeClass('active');
// ----------------- execution context ------------- $('#optionViews').attr('class', '').addClass(cls);
$el.addClass('active');
var $vmToggle = $('#vm'); } else {
var $web3Toggle = $('#web3'); $el.removeClass('active');
var $web3endpoint = $('#web3Endpoint'); $('#optionViews').removeClass(cls);
}
if (typeof web3 !== 'undefined') });
{
if (web3.providers && web3.currentProvider instanceof web3.providers.IpcProvider) // ----------------- execution context -------------
$web3endpoint.val('ipc');
web3 = new Web3(web3.currentProvider); var $vmToggle = $('#vm');
} else var $web3Toggle = $('#web3');
web3 = new Web3(new Web3.providers.HttpProvider("http://localhost:8545")); var $web3endpoint = $('#web3Endpoint');
var executionContext = 'vm'; if (typeof web3 !== 'undefined')
$vmToggle.get(0).checked = true; {
if (web3.providers && web3.currentProvider instanceof web3.providers.IpcProvider)
$vmToggle.on('change', executionContextChange ); $web3endpoint.val('ipc');
$web3Toggle.on('change', executionContextChange ); web3 = new Web3(web3.currentProvider);
$web3endpoint.on('change', function() { } else
var endpoint = $web3endpoint.val(); web3 = new Web3(new Web3.providers.HttpProvider("http://localhost:8545"));
if (endpoint == 'ipc')
web3.setProvider(new Web3.providers.IpcProvider()); var executionContext = 'vm';
else $vmToggle.get(0).checked = true;
web3.setProvider(new Web3.providers.HttpProvider(endpoint));
compile(); $vmToggle.on('change', executionContextChange );
}); $web3Toggle.on('change', executionContextChange );
$web3endpoint.on('change', function() {
function executionContextChange (ev) { var endpoint = $web3endpoint.val();
if (ev.target.value == 'web3' && !confirm("Are you sure you want to connect to a local ethereum node?") ) { if (endpoint == 'ipc')
$vmToggle.get(0).checked = true; web3.setProvider(new Web3.providers.IpcProvider());
executionContext = 'vm'; else
} else executionContext = ev.target.value; web3.setProvider(new Web3.providers.HttpProvider(endpoint));
compile(); compile();
} });
function executionContextChange (ev) {
if (ev.target.value == 'web3' && !confirm("Are you sure you want to connect to a local ethereum node?") ) {
// ------------------ gist publish -------------- $vmToggle.get(0).checked = true;
executionContext = 'vm';
$('#gist').click(function(){ } else executionContext = ev.target.value;
if (confirm("Are you sure you want to publish all your files anonymously as a public gist on github.com?")) { compile();
}
// ------------------ gist publish --------------
$('#gist').click(function(){
if (confirm("Are you sure you want to publish all your files anonymously as a public gist on github.com?")) {
var files = {}; var files = {};
var filesArr = getFiles(); var filesArr = getFiles();
...@@ -254,506 +254,506 @@ ...@@ -254,506 +254,506 @@
for(var f in filesArr) { for(var f in filesArr) {
files[fileNameFromKey(filesArr[f])] = { files[fileNameFromKey(filesArr[f])] = {
content: localStorage[filesArr[f]] content: localStorage[filesArr[f]]
}; };
} }
$.ajax({ $.ajax({
url: 'https://api.github.com/gists', url: 'https://api.github.com/gists',
type: 'POST', type: 'POST',
data: JSON.stringify({ data: JSON.stringify({
description: description, description: description,
public: true, public: true,
files: files files: files
}) })
}).done(function(response) { }).done(function(response) {
if (response.html_url && confirm("Created a gist at " + response.html_url + " Would you like to open it in a new window?")) { if (response.html_url && confirm("Created a gist at " + response.html_url + " Would you like to open it in a new window?")) {
window.open( response.html_url, '_blank' ); window.open( response.html_url, '_blank' );
} }
}); });
} }
}); });
// ----------------- file selector------------- // ----------------- file selector-------------
var $filesEl = $('#files'); var $filesEl = $('#files');
var FILE_SCROLL_DELTA = 300; var FILE_SCROLL_DELTA = 300;
$('.newFile').on('click', function() { $('.newFile').on('click', function() {
while (window.localStorage[SOL_CACHE_UNTITLED + untitledCount]) while (window.localStorage[SOL_CACHE_UNTITLED + untitledCount])
untitledCount = (untitledCount - 0) + 1; untitledCount = (untitledCount - 0) + 1;
SOL_CACHE_FILE = SOL_CACHE_UNTITLED + untitledCount; SOL_CACHE_FILE = SOL_CACHE_UNTITLED + untitledCount;
window.localStorage[SOL_CACHE_FILE] = ''; window.localStorage[SOL_CACHE_FILE] = '';
updateFiles(); updateFiles();
$filesEl.animate({left: Math.max( (0 - activeFilePos() + (FILE_SCROLL_DELTA/2)), 0)+ "px"}, "slow", function(){ $filesEl.animate({left: Math.max( (0 - activeFilePos() + (FILE_SCROLL_DELTA/2)), 0)+ "px"}, "slow", function(){
reAdjust(); reAdjust();
}) })
}); });
$filesEl.on('click', '.file:not(.active)', showFileHandler); $filesEl.on('click', '.file:not(.active)', showFileHandler);
$filesEl.on('click', '.file.active', function(ev) { $filesEl.on('click', '.file.active', function(ev) {
var $fileTabEl = $(this); var $fileTabEl = $(this);
var originalName = $fileTabEl.find('.name').text(); var originalName = $fileTabEl.find('.name').text();
ev.preventDefault(); ev.preventDefault();
if ($(this).find('input').length > 0) return false; if ($(this).find('input').length > 0) return false;
var $fileNameInputEl = $('<input value="'+originalName+'"/>'); var $fileNameInputEl = $('<input value="'+originalName+'"/>');
$fileTabEl.html($fileNameInputEl); $fileTabEl.html($fileNameInputEl);
$fileNameInputEl.focus(); $fileNameInputEl.focus();
$fileNameInputEl.select(); $fileNameInputEl.select();
$fileNameInputEl.on('blur', handleRename); $fileNameInputEl.on('blur', handleRename);
$fileNameInputEl.keyup(handleRename); $fileNameInputEl.keyup(handleRename);
function handleRename(ev) { function handleRename(ev) {
ev.preventDefault(); ev.preventDefault();
if (ev.which && ev.which !== 13) return false; if (ev.which && ev.which !== 13) return false;
var newName = ev.target.value; var newName = ev.target.value;
$fileNameInputEl.off('blur'); $fileNameInputEl.off('blur');
$fileNameInputEl.off('keyup'); $fileNameInputEl.off('keyup');
if (newName !== originalName && confirm("Are you sure you want to rename: " + originalName + " to " + newName + '?')) { if (newName !== originalName && confirm("Are you sure you want to rename: " + originalName + " to " + newName + '?')) {
var content = window.localStorage.getItem( fileKey(originalName) ); var content = window.localStorage.getItem( fileKey(originalName) );
window.localStorage[fileKey( newName )] = content; window.localStorage[fileKey( newName )] = content;
window.localStorage.removeItem( fileKey( originalName) ); window.localStorage.removeItem( fileKey( originalName) );
SOL_CACHE_FILE = fileKey( newName ); SOL_CACHE_FILE = fileKey( newName );
} }
updateFiles(); updateFiles();
return false; return false;
} }
return false; return false;
}) })
$filesEl.on('click', '.file .remove', function(ev) { $filesEl.on('click', '.file .remove', function(ev) {
ev.preventDefault(); ev.preventDefault();
var name = $(this).parent().find('.name').text(); var name = $(this).parent().find('.name').text();
var index = getFiles().indexOf( fileKey(name) ); var index = getFiles().indexOf( fileKey(name) );
if (confirm("Are you sure you want to remove: " + name + " from local storage?")) { if (confirm("Are you sure you want to remove: " + name + " from local storage?")) {
window.localStorage.removeItem( fileKey( name ) ); window.localStorage.removeItem( fileKey( name ) );
SOL_CACHE_FILE = getFiles()[ Math.max(0, index - 1)]; SOL_CACHE_FILE = getFiles()[ Math.max(0, index - 1)];
updateFiles(); updateFiles();
} }
return false; return false;
}); });
function showFileHandler(ev) { function showFileHandler(ev) {
ev.preventDefault(); ev.preventDefault();
SOL_CACHE_FILE = fileKey( $(this).find('.name').text() ); SOL_CACHE_FILE = fileKey( $(this).find('.name').text() );
updateFiles(); updateFiles();
return false; return false;
} }
function fileTabFromKey(key) { function fileTabFromKey(key) {
var name = fileNameFromKey(key); var name = fileNameFromKey(key);
return $('#files .file').filter(function(){ return $(this).find('.name').text() == name; }); return $('#files .file').filter(function(){ return $(this).find('.name').text() == name; });
} }
function updateFiles() { function updateFiles() {
var $filesEl = $('#files'); var $filesEl = $('#files');
var files = getFiles(); var files = getFiles();
$filesEl.find('.file').remove(); $filesEl.find('.file').remove();
for (var f in files) { for (var f in files) {
$filesEl.append(fileTabTemplate(files[f])); $filesEl.append(fileTabTemplate(files[f]));
} }
if (SOL_CACHE_FILE) { if (SOL_CACHE_FILE) {
var active = fileTabFromKey(SOL_CACHE_FILE); var active = fileTabFromKey(SOL_CACHE_FILE);
active.addClass('active'); active.addClass('active');
editor.setSession( sessions[SOL_CACHE_FILE] ); editor.setSession( sessions[SOL_CACHE_FILE] );
editor.focus(); editor.focus();
} }
$('#input').toggle( !!SOL_CACHE_FILE ); $('#input').toggle( !!SOL_CACHE_FILE );
$('#output').toggle( !!SOL_CACHE_FILE ); $('#output').toggle( !!SOL_CACHE_FILE );
reAdjust(); reAdjust();
} }
function fileTabTemplate(key) { function fileTabTemplate(key) {
var name = fileNameFromKey(key); var name = fileNameFromKey(key);
return $('<li class="file"><span class="name">'+name+'</span><span class="remove"><i class="fa fa-close"></i></span></li>'); return $('<li class="file"><span class="name">'+name+'</span><span class="remove"><i class="fa fa-close"></i></span></li>');
} }
function fileKey( name ) { function fileKey( name ) {
return SOL_CACHE_FILE_PREFIX + name; return SOL_CACHE_FILE_PREFIX + name;
} }
function fileNameFromKey(key) { function fileNameFromKey(key) {
return key.replace( SOL_CACHE_FILE_PREFIX, '' ); return key.replace( SOL_CACHE_FILE_PREFIX, '' );
} }
function getFiles() { function getFiles() {
var files = []; var files = [];
for (var f in localStorage ) { for (var f in localStorage ) {
if (f.indexOf( SOL_CACHE_FILE_PREFIX, 0 ) === 0) { if (f.indexOf( SOL_CACHE_FILE_PREFIX, 0 ) === 0) {
files.push(f); files.push(f);
if (!sessions[f]) sessions[f] = newEditorSession(f); if (!sessions[f]) sessions[f] = newEditorSession(f);
} }
} }
return files; return files;
} }
$filesWrapper = $('.files-wrapper'); $filesWrapper = $('.files-wrapper');
$scrollerRight = $('.scroller-right'); $scrollerRight = $('.scroller-right');
$scrollerLeft = $('.scroller-left'); $scrollerLeft = $('.scroller-left');
function widthOfList (){ function widthOfList (){
var itemsWidth = 0; var itemsWidth = 0;
$('.file').each(function(){ $('.file').each(function(){
var itemWidth = $(this).outerWidth(); var itemWidth = $(this).outerWidth();
itemsWidth += itemWidth; itemsWidth += itemWidth;
}); });
return itemsWidth; return itemsWidth;
}; };
function widthOfHidden(){ function widthOfHidden(){
return (($filesWrapper.outerWidth()) - widthOfList() - getLeftPosi()); return (($filesWrapper.outerWidth()) - widthOfList() - getLeftPosi());
}; };
function widthOfVisible(){ function widthOfVisible(){
return $filesWrapper.outerWidth(); return $filesWrapper.outerWidth();
}; };
function getLeftPosi(){ function getLeftPosi(){
return $filesEl.position().left; return $filesEl.position().left;
}; };
function activeFilePos() { function activeFilePos() {
var el = $filesEl.find('.active'); var el = $filesEl.find('.active');
var l = el.position().left; var l = el.position().left;
return l; return l;
} }
function reAdjust (){ function reAdjust (){
if (widthOfList() + getLeftPosi() > + widthOfVisible()) { if (widthOfList() + getLeftPosi() > + widthOfVisible()) {
$scrollerRight.fadeIn('fast'); $scrollerRight.fadeIn('fast');
} else { } else {
$scrollerRight.fadeOut('fast'); $scrollerRight.fadeOut('fast');
} }
if (getLeftPosi()<0) { if (getLeftPosi()<0) {
$scrollerLeft.fadeIn('fast'); $scrollerLeft.fadeIn('fast');
} else { } else {
$scrollerLeft.fadeOut('fast'); $scrollerLeft.fadeOut('fast');
$filesEl.animate({left: getLeftPosi() + "px"},'slow'); $filesEl.animate({left: getLeftPosi() + "px"},'slow');
} }
} }
$scrollerRight.click(function() { $scrollerRight.click(function() {
var delta = (getLeftPosi() - FILE_SCROLL_DELTA) var delta = (getLeftPosi() - FILE_SCROLL_DELTA)
$filesEl.animate({left: delta + "px"},'slow',function(){ $filesEl.animate({left: delta + "px"},'slow',function(){
reAdjust(); reAdjust();
}); });
}); });
$scrollerLeft.click(function() { $scrollerLeft.click(function() {
var delta = Math.min( (getLeftPosi() + FILE_SCROLL_DELTA), 0 ) var delta = Math.min( (getLeftPosi() + FILE_SCROLL_DELTA), 0 )
$filesEl.animate({left: delta + "px"},'slow',function(){ $filesEl.animate({left: delta + "px"},'slow',function(){
reAdjust(); reAdjust();
}); });
}); });
updateFiles(); updateFiles();
// ----------------- version selector------------- // ----------------- version selector-------------
// var soljsonSources is provided by bin/list.js // var soljsonSources is provided by bin/list.js
$('option', '#versionSelector').remove(); $('option', '#versionSelector').remove();
$.each(soljsonSources, function(i, file) { $.each(soljsonSources, function(i, file) {
if (file) { if (file) {
var version = file.replace(/soljson-(.*).js/, "$1"); var version = file.replace(/soljson-(.*).js/, "$1");
$('#versionSelector').append(new Option(version, file)); $('#versionSelector').append(new Option(version, file));
} }
}); });
$('#versionSelector').change(function() { $('#versionSelector').change(function() {
updateQueryParams({version: $('#versionSelector').val() }); updateQueryParams({version: $('#versionSelector').val() });
loadVersion($('#versionSelector').val()); loadVersion($('#versionSelector').val());
}); });
// ----------------- resizeable ui --------------- // ----------------- resizeable ui ---------------
var EDITOR_SIZE_CACHE_KEY = "editor-size-cache"; var EDITOR_SIZE_CACHE_KEY = "editor-size-cache";
var dragging = false; var dragging = false;
$('#dragbar').mousedown(function(e){ $('#dragbar').mousedown(function(e){
e.preventDefault(); e.preventDefault();
dragging = true; dragging = true;
var main = $('#righthand-panel'); var main = $('#righthand-panel');
var ghostbar = $('<div id="ghostbar">', { var ghostbar = $('<div id="ghostbar">', {
css: { css: {
top: main.offset().top, top: main.offset().top,
left: main.offset().left left: main.offset().left
} }
}).prependTo('body'); }).prependTo('body');
$(document).mousemove(function(e){ $(document).mousemove(function(e){
ghostbar.css("left",e.pageX+2); ghostbar.css("left",e.pageX+2);
}); });
}); });
var $body = $('body'); var $body = $('body');
function setEditorSize (delta) { function setEditorSize (delta) {
$('#righthand-panel').css("width", delta); $('#righthand-panel').css("width", delta);
$('#editor').css("right", delta); $('#editor').css("right", delta);
onResize(); onResize();
} }
function getEditorSize(){ function getEditorSize(){
window.localStorage[EDITOR_SIZE_CACHE_KEY] = $('#righthand-panel').width(); window.localStorage[EDITOR_SIZE_CACHE_KEY] = $('#righthand-panel').width();
} }
$(document).mouseup(function(e){ $(document).mouseup(function(e){
if (dragging) { if (dragging) {
var delta = $body.width() - e.pageX+2; var delta = $body.width() - e.pageX+2;
$('#ghostbar').remove(); $('#ghostbar').remove();
$(document).unbind('mousemove'); $(document).unbind('mousemove');
dragging = false; dragging = false;
setEditorSize(delta); setEditorSize(delta);
window.localStorage.setItem(EDITOR_SIZE_CACHE_KEY, delta); window.localStorage.setItem(EDITOR_SIZE_CACHE_KEY, delta);
reAdjust(); reAdjust();
} }
}); });
// set cached defaults // set cached defaults
var cachedSize = window.localStorage.getItem(EDITOR_SIZE_CACHE_KEY); var cachedSize = window.localStorage.getItem(EDITOR_SIZE_CACHE_KEY);
if (cachedSize) setEditorSize(cachedSize); if (cachedSize) setEditorSize(cachedSize);
else getEditorSize(); else getEditorSize();
// ----------------- toggle right hand panel ----------------- // ----------------- toggle right hand panel -----------------
var hidingRHP = false; var hidingRHP = false;
$('.toggleRHP').click(function(){ $('.toggleRHP').click(function(){
hidingRHP = !hidingRHP; hidingRHP = !hidingRHP;
setEditorSize( hidingRHP ? 0 : window.localStorage[EDITOR_SIZE_CACHE_KEY] ); setEditorSize( hidingRHP ? 0 : window.localStorage[EDITOR_SIZE_CACHE_KEY] );
$('.toggleRHP i').toggleClass('fa-angle-double-right', !hidingRHP); $('.toggleRHP i').toggleClass('fa-angle-double-right', !hidingRHP);
$('.toggleRHP i').toggleClass('fa-angle-double-left', hidingRHP); $('.toggleRHP i').toggleClass('fa-angle-double-left', hidingRHP);
if (!hidingRHP) compile(); if (!hidingRHP) compile();
}); });
// ----------------- editor resize --------------- // ----------------- editor resize ---------------
function onResize() { function onResize() {
editor.resize(); editor.resize();
var session = editor.getSession(); var session = editor.getSession();
session.setUseWrapMode(document.querySelector('#editorWrap').checked); session.setUseWrapMode(document.querySelector('#editorWrap').checked);
if(session.getUseWrapMode()) { if(session.getUseWrapMode()) {
var characterWidth = editor.renderer.characterWidth; var characterWidth = editor.renderer.characterWidth;
var contentWidth = editor.container.ownerDocument.getElementsByClassName("ace_scroller")[0].clientWidth; var contentWidth = editor.container.ownerDocument.getElementsByClassName("ace_scroller")[0].clientWidth;
if(contentWidth > 0) { if(contentWidth > 0) {
session.setWrapLimit(parseInt(contentWidth / characterWidth, 10)); session.setWrapLimit(parseInt(contentWidth / characterWidth, 10));
} }
} }
reAdjust(); reAdjust();
} }
window.onresize = onResize; window.onresize = onResize;
onResize(); onResize();
document.querySelector('#editor').addEventListener('change', onResize); document.querySelector('#editor').addEventListener('change', onResize);
document.querySelector('#editorWrap').addEventListener('change', onResize); document.querySelector('#editorWrap').addEventListener('change', onResize);
// ----------------- compiler ---------------------- // ----------------- compiler ----------------------
var compileJSON; var compileJSON;
var compilerAcceptsMultipleFiles; var compilerAcceptsMultipleFiles;
var previousInput = ''; var previousInput = '';
var sourceAnnotations = []; var sourceAnnotations = [];
var compile = function(missingInputs) { var compile = function(missingInputs) {
editor.getSession().clearAnnotations(); editor.getSession().clearAnnotations();
sourceAnnotations = []; sourceAnnotations = [];
editor.getSession().removeMarker(errMarkerId); editor.getSession().removeMarker(errMarkerId);
$('#output').empty(); $('#output').empty();
var input = editor.getValue(); var input = editor.getValue();
window.localStorage.setItem(SOL_CACHE_FILE, input); window.localStorage.setItem(SOL_CACHE_FILE, input);
var files = {}; var files = {};
files[fileNameFromKey(SOL_CACHE_FILE)] = input; files[fileNameFromKey(SOL_CACHE_FILE)] = input;
gatherImports(files, missingInputs, function(input, error) { gatherImports(files, missingInputs, function(input, error) {
$('#output').empty(); $('#output').empty();
if (input === null) { if (input === null) {
renderError(error); renderError(error);
} else { } else {
var optimize = getQueryParams().optimize; var optimize = getQueryParams().optimize;
compileJSON(input, optimize ? 1 : 0); compileJSON(input, optimize ? 1 : 0);
} }
}); });
}; };
var compilationFinished = function(result, missingInputs) { var compilationFinished = function(result, missingInputs) {
var data = $.parseJSON(result); var data = $.parseJSON(result);
var noFatalErrors = true; // ie warnings are ok var noFatalErrors = true; // ie warnings are ok
if (data['error'] !== undefined) { if (data['error'] !== undefined) {
renderError(data['error']); renderError(data['error']);
if (errortype(data['error']) !== 'warning') noFatalErrors = false; if (errortype(data['error']) !== 'warning') noFatalErrors = false;
} }
if (data['errors'] != undefined) { if (data['errors'] != undefined) {
$.each(data['errors'], function(i, err) { $.each(data['errors'], function(i, err) {
renderError(err); renderError(err);
if (errortype(err) !== 'warning') noFatalErrors = false; if (errortype(err) !== 'warning') noFatalErrors = false;
}); });
} }
if (missingInputs !== undefined && missingInputs.length > 0) if (missingInputs !== undefined && missingInputs.length > 0)
compile(missingInputs); compile(missingInputs);
else if (noFatalErrors && !hidingRHP) else if (noFatalErrors && !hidingRHP)
renderContracts(data, editor.getValue()); renderContracts(data, editor.getValue());
}; };
var compileTimeout = null; var compileTimeout = null;
var onChange = function() { var onChange = function() {
var input = editor.getValue(); var input = editor.getValue();
if (input === "") { if (input === "") {
window.localStorage.setItem(SOL_CACHE_FILE, ''); window.localStorage.setItem(SOL_CACHE_FILE, '');
return; return;
} }
if (input === previousInput) if (input === previousInput)
return; return;
previousInput = input; previousInput = input;
if (compileTimeout) window.clearTimeout(compileTimeout); if (compileTimeout) window.clearTimeout(compileTimeout);
compileTimeout = window.setTimeout(compile, 300); compileTimeout = window.setTimeout(compile, 300);
}; };
var onCompilerLoaded = function() { var onCompilerLoaded = function() {
if (worker === null) { if (worker === null) {
var compile; var compile;
var missingInputs = []; var missingInputs = [];
if ('_compileJSONCallback' in Module) { if ('_compileJSONCallback' in Module) {
compilerAcceptsMultipleFiles = true; compilerAcceptsMultipleFiles = true;
var missingInputsCallback = Module.Runtime.addFunction(function(path, contents, error) { var missingInputsCallback = Module.Runtime.addFunction(function(path, contents, error) {
missingInputs.push(Module.Pointer_stringify(path)); missingInputs.push(Module.Pointer_stringify(path));
}); });
var compileInternal = Module.cwrap("compileJSONCallback", "string", ["string", "number", "number"]); var compileInternal = Module.cwrap("compileJSONCallback", "string", ["string", "number", "number"]);
compile = function(input, optimize) { compile = function(input, optimize) {
missingInputs.length = 0; missingInputs.length = 0;
return compileInternal(input, optimize, missingInputsCallback); return compileInternal(input, optimize, missingInputsCallback);
}; };
} else if ('_compileJSONMulti' in Module) { } else if ('_compileJSONMulti' in Module) {
compilerAcceptsMultipleFiles = true; compilerAcceptsMultipleFiles = true;
compile = Module.cwrap("compileJSONMulti", "string", ["string", "number"]); compile = Module.cwrap("compileJSONMulti", "string", ["string", "number"]);
} else { } else {
compilerAcceptsMultipleFiles = false; compilerAcceptsMultipleFiles = false;
compile = Module.cwrap("compileJSON", "string", ["string", "number"]); compile = Module.cwrap("compileJSON", "string", ["string", "number"]);
} }
compileJSON = function(source, optimize, cb) { compileJSON = function(source, optimize, cb) {
try { try {
var result = compile(source, optimize); var result = compile(source, optimize);
} catch (exception) { } catch (exception) {
result = JSON.stringify({error: 'Uncaught JavaScript exception:\n' + exception}); result = JSON.stringify({error: 'Uncaught JavaScript exception:\n' + exception});
} }
compilationFinished(result, missingInputs); compilationFinished(result, missingInputs);
}; };
$('#version').text(Module.cwrap("version", "string", [])()); $('#version').text(Module.cwrap("version", "string", [])());
} }
previousInput = ''; previousInput = '';
onChange(); onChange();
}; };
var cachedRemoteFiles = {}; var cachedRemoteFiles = {};
function gatherImports(files, importHints, cb) { function gatherImports(files, importHints, cb) {
importHints = importHints || []; importHints = importHints || [];
if (!compilerAcceptsMultipleFiles) if (!compilerAcceptsMultipleFiles)
{ {
cb(files[fileNameFromKey(SOL_CACHE_FILE)]); cb(files[fileNameFromKey(SOL_CACHE_FILE)]);
return; return;
} }
var importRegex = /import\s[\'\"]([^\'\"]+)[\'\"];/g; var importRegex = /import\s[\'\"]([^\'\"]+)[\'\"];/g;
var reloop = false; var reloop = false;
do { do {
reloop = false; reloop = false;
for (var fileName in files) { for (var fileName in files) {
var match; var match;
while (match = importRegex.exec(files[fileName])) while (match = importRegex.exec(files[fileName]))
importHints.push(match[1]); importHints.push(match[1]);
} }
while (importHints.length > 0) { while (importHints.length > 0) {
var m = importHints.pop(); var m = importHints.pop();
if (m in files) continue; if (m in files) continue;
if (getFiles().indexOf(fileKey(m)) !== -1) { if (getFiles().indexOf(fileKey(m)) !== -1) {
files[m] = window.localStorage[fileKey(m)]; files[m] = window.localStorage[fileKey(m)];
reloop = true; reloop = true;
} else if (m in cachedRemoteFiles) { } else if (m in cachedRemoteFiles) {
files[m] = cachedRemoteFiles[m]; files[m] = cachedRemoteFiles[m];
reloop = true; reloop = true;
} else if (githubMatch = /^(https?:\/\/)?(www.)?github.com\/([^\/]*\/[^\/]*)\/(.*)/.exec(m)) { } else if (githubMatch = /^(https?:\/\/)?(www.)?github.com\/([^\/]*\/[^\/]*)\/(.*)/.exec(m)) {
$('#output').append($('<div/>').append($('<pre/>').text("Loading github.com/" + githubMatch[3] + " ..."))); $('#output').append($('<div/>').append($('<pre/>').text("Loading github.com/" + githubMatch[3] + " ...")));
$.getJSON('https://api.github.com/repos/' + githubMatch[3] + '/contents/' + githubMatch[4], function(result) { $.getJSON('https://api.github.com/repos/' + githubMatch[3] + '/contents/' + githubMatch[4], function(result) {
if ('content' in result) if ('content' in result)
{ {
var content = Base64.decode(result.content); var content = Base64.decode(result.content);
cachedRemoteFiles[m] = content; cachedRemoteFiles[m] = content;
files[m] = content; files[m] = content;
gatherImports(files, importHints, cb); gatherImports(files, importHints, cb);
} }
else else
cb(null, "Unable to import \"" + m + "\""); cb(null, "Unable to import \"" + m + "\"");
}).fail(function(){ }).fail(function(){
cb(null, "Unable to import \"" + m + "\""); cb(null, "Unable to import \"" + m + "\"");
}); });
return; return;
} else { } else {
cb(null, "Unable to import \"" + m + "\""); cb(null, "Unable to import \"" + m + "\"");
return; return;
} }
} }
} while (reloop); } while (reloop);
cb(JSON.stringify({'sources':files})); cb(JSON.stringify({'sources':files}));
} }
var initializeWorker = function() { var initializeWorker = function() {
if (worker !== null) if (worker !== null)
worker.terminate(); worker.terminate();
worker = new Worker('worker.js'); worker = new Worker('worker.js');
worker.addEventListener('message', function(msg) { worker.addEventListener('message', function(msg) {
var data = msg.data; var data = msg.data;
switch (data.cmd) { switch (data.cmd) {
case 'versionLoaded': case 'versionLoaded':
$('#version').text(data.data); $('#version').text(data.data);
compilerAcceptsMultipleFiles = !!data.acceptsMultipleFiles; compilerAcceptsMultipleFiles = !!data.acceptsMultipleFiles;
onCompilerLoaded(); onCompilerLoaded();
break; break;
case 'compiled': case 'compiled':
compilationFinished(data.data, data.missingInputs); compilationFinished(data.data, data.missingInputs);
break; break;
}; };
}); });
worker.onerror = function(msg) { console.log(msg.data); }; worker.onerror = function(msg) { console.log(msg.data); };
worker.addEventListener('error', function(msg) { console.log(msg.data); }); worker.addEventListener('error', function(msg) { console.log(msg.data); });
compileJSON = function(source, optimize) { compileJSON = function(source, optimize) {
worker.postMessage({cmd: 'compile', source: source, optimize: optimize}); worker.postMessage({cmd: 'compile', source: source, optimize: optimize});
}; };
}; };
var worker = null; var worker = null;
var loadVersion = function(version) { var loadVersion = function(version) {
$('#version').text("(loading)"); $('#version').text("(loading)");
updateQueryParams({version: version}); updateQueryParams({version: version});
var isFirefox = typeof InstallTrigger !== 'undefined'; var isFirefox = typeof InstallTrigger !== 'undefined';
if (document.location.protocol != 'file:' && Worker !== undefined && isFirefox) { if (document.location.protocol != 'file:' && Worker !== undefined && isFirefox) {
// Workers cannot load js on "file:"-URLs and we get a // Workers cannot load js on "file:"-URLs and we get a
// "Uncaught RangeError: Maximum call stack size exceeded" error on Chromium, // "Uncaught RangeError: Maximum call stack size exceeded" error on Chromium,
// resort to non-worker version in that case. // resort to non-worker version in that case.
initializeWorker(); initializeWorker();
worker.postMessage({cmd: 'loadVersion', data: 'https://ethereum.github.io/solc-bin/bin/' + version}); worker.postMessage({cmd: 'loadVersion', data: 'https://ethereum.github.io/solc-bin/bin/' + version});
} else { } else {
Module = null; Module = null;
compileJSON = function(source, optimize) { compilationFinished('{}'); }; compileJSON = function(source, optimize) { compilationFinished('{}'); };
var newScript = document.createElement('script'); var newScript = document.createElement('script');
newScript.type = 'text/javascript'; newScript.type = 'text/javascript';
newScript.src = 'https://ethereum.github.io/solc-bin/bin/' + version; newScript.src = 'https://ethereum.github.io/solc-bin/bin/' + version;
document.getElementsByTagName("head")[0].appendChild(newScript); document.getElementsByTagName("head")[0].appendChild(newScript);
var check = window.setInterval(function() { var check = window.setInterval(function() {
if (!Module) return; if (!Module) return;
window.clearInterval(check); window.clearInterval(check);
onCompilerLoaded(); onCompilerLoaded();
}, 200); }, 200);
} }
}; };
...@@ -773,225 +773,225 @@ ...@@ -773,225 +773,225 @@
// ----------------- compiler output renderer ---------------------- // ----------------- compiler output renderer ----------------------
var detailsOpen = {}; var detailsOpen = {};
function errortype(message) { function errortype(message) {
return message.match(/^.*:[0-9]*:[0-9]* Warning: /) ? 'warning' : 'error'; return message.match(/^.*:[0-9]*:[0-9]* Warning: /) ? 'warning' : 'error';
} }
var renderError = function(message) { var renderError = function(message) {
var type = errortype(message); var type = errortype(message);
var $pre = $("<pre />").text(message); var $pre = $("<pre />").text(message);
var $error = $('<div class="sol ' + type + '"><div class="close"><i class="fa fa-close"></i></div></div>').prepend($pre); var $error = $('<div class="sol ' + type + '"><div class="close"><i class="fa fa-close"></i></div></div>').prepend($pre);
$('#output').append( $error ); $('#output').append( $error );
var err = message.match(/^([^:]*):([0-9]*):(([0-9]*):)? /); var err = message.match(/^([^:]*):([0-9]*):(([0-9]*):)? /);
if (err) { if (err) {
var errFile = err[1]; var errFile = err[1];
var errLine = parseInt(err[2], 10) - 1; var errLine = parseInt(err[2], 10) - 1;
var errCol = err[4] ? parseInt(err[4], 10) : 0; var errCol = err[4] ? parseInt(err[4], 10) : 0;
if (errFile == '' || errFile == fileNameFromKey(SOL_CACHE_FILE)) { if (errFile == '' || errFile == fileNameFromKey(SOL_CACHE_FILE)) {
sourceAnnotations[sourceAnnotations.length] = { sourceAnnotations[sourceAnnotations.length] = {
row: errLine, row: errLine,
column: errCol, column: errCol,
text: message, text: message,
type: type type: type
}; };
editor.getSession().setAnnotations(sourceAnnotations); editor.getSession().setAnnotations(sourceAnnotations);
} }
$error.click(function(ev){ $error.click(function(ev){
if (errFile != '' && errFile != fileNameFromKey(SOL_CACHE_FILE) && getFiles().indexOf(fileKey(errFile)) !== -1) { if (errFile != '' && errFile != fileNameFromKey(SOL_CACHE_FILE) && getFiles().indexOf(fileKey(errFile)) !== -1) {
// Switch to file // Switch to file
SOL_CACHE_FILE = fileKey(errFile); SOL_CACHE_FILE = fileKey(errFile);
updateFiles(); updateFiles();
//@TODO could show some error icon in files with errors //@TODO could show some error icon in files with errors
} }
editor.focus(); editor.focus();
editor.gotoLine(errLine + 1, errCol - 1, true); editor.gotoLine(errLine + 1, errCol - 1, true);
}); });
$error.find('.close').click(function(ev){ $error.find('.close').click(function(ev){
ev.preventDefault(); ev.preventDefault();
$error.remove(); $error.remove();
return false; return false;
}); });
} }
}; };
var gethDeploy = function(contractName, interface, bytecode){ var gethDeploy = function(contractName, interface, bytecode){
var code = ""; var code = "";
var funABI = getConstructorInterface($.parseJSON(interface)); var funABI = getConstructorInterface($.parseJSON(interface));
$.each(funABI.inputs, function(i, inp) { $.each(funABI.inputs, function(i, inp) {
code += "var " + inp.name + " = /* var of type " + inp.type + " here */ ;\n"; code += "var " + inp.name + " = /* var of type " + inp.type + " here */ ;\n";
}); });
code += "var " + contractName + "Contract = web3.eth.contract(" + interface.replace("\n","") + ");" code += "var " + contractName + "Contract = web3.eth.contract(" + interface.replace("\n","") + ");"
+"\nvar " + contractName + " = " + contractName + "Contract.new("; +"\nvar " + contractName + " = " + contractName + "Contract.new(";
$.each(funABI.inputs, function(i, inp) { $.each(funABI.inputs, function(i, inp) {
code += "\n " + inp.name + ","; code += "\n " + inp.name + ",";
}); });
code += "\n {"+ code += "\n {"+
"\n from: web3.eth.accounts[0], "+ "\n from: web3.eth.accounts[0], "+
"\n data: '"+bytecode+"', "+ "\n data: '"+bytecode+"', "+
"\n gas: 3000000"+ "\n gas: 3000000"+
"\n }, function(e, contract){"+ "\n }, function(e, contract){"+
"\n console.log(e, contract);"+ "\n console.log(e, contract);"+
"\n if (typeof contract.address != 'undefined') {"+ "\n if (typeof contract.address != 'undefined') {"+
"\n console.log('Contract mined! address: ' + contract.address + ' transactionHash: ' + contract.transactionHash);" + "\n console.log('Contract mined! address: ' + contract.address + ' transactionHash: ' + contract.transactionHash);" +
"\n }" + "\n }" +
"\n })"; "\n })";
return code; return code;
}; };
var combined = function(contractName, interface, bytecode){ var combined = function(contractName, interface, bytecode){
return JSON.stringify([{name: contractName, interface: interface, bytecode: bytecode}]); return JSON.stringify([{name: contractName, interface: interface, bytecode: bytecode}]);
}; };
var renderContracts = function(data, source) { var renderContracts = function(data, source) {
var udappContracts = []; var udappContracts = [];
for (var contractName in data.contracts) { for (var contractName in data.contracts) {
var contract = data.contracts[contractName]; var contract = data.contracts[contractName];
udappContracts.push({ udappContracts.push({
name: contractName, name: contractName,
interface: contract['interface'], interface: contract['interface'],
bytecode: contract.bytecode bytecode: contract.bytecode
}); });
} }
var dapp = new UniversalDApp(udappContracts, { var dapp = new UniversalDApp(udappContracts, {
vm: executionContext === 'vm', vm: executionContext === 'vm',
removable: false, removable: false,
getAddress: function(){ return $('#txorigin').val(); }, getAddress: function(){ return $('#txorigin').val(); },
getValue: function(){ getValue: function(){
var comp = $('#value').val().split(' '); var comp = $('#value').val().split(' ');
return web3.toWei(comp[0], comp.slice(1).join(' ')); return web3.toWei(comp[0], comp.slice(1).join(' '));
}, },
removable_instances: true, removable_instances: true,
renderOutputModifier: function(contractName, $contractOutput) { renderOutputModifier: function(contractName, $contractOutput) {
var contract = data.contracts[contractName]; var contract = data.contracts[contractName];
return $contractOutput return $contractOutput
.append(textRow('Bytecode', contract.bytecode)) .append(textRow('Bytecode', contract.bytecode))
.append(textRow('Interface', contract['interface'])) .append(textRow('Interface', contract['interface']))
.append(textRow('Web3 deploy', gethDeploy(contractName.toLowerCase(),contract['interface'],contract.bytecode), 'deploy')) .append(textRow('Web3 deploy', gethDeploy(contractName.toLowerCase(),contract['interface'],contract.bytecode), 'deploy'))
.append(textRow('uDApp', combined(contractName,contract['interface'],contract.bytecode), 'deploy')) .append(textRow('uDApp', combined(contractName,contract['interface'],contract.bytecode), 'deploy'))
.append(getDetails(contract, source, contractName)); .append(getDetails(contract, source, contractName));
}}); }});
var $contractOutput = dapp.render(); var $contractOutput = dapp.render();
$txOrigin = $('#txorigin'); $txOrigin = $('#txorigin');
function renderAccounts(err, accounts) { function renderAccounts(err, accounts) {
if (err) if (err)
renderError(err.message); renderError(err.message);
if (accounts && accounts[0]){ if (accounts && accounts[0]){
$txOrigin.empty(); $txOrigin.empty();
for( var a in accounts) { $txOrigin.append($('<option />').val(accounts[a]).text(accounts[a])); } for( var a in accounts) { $txOrigin.append($('<option />').val(accounts[a]).text(accounts[a])); }
$txOrigin.val(accounts[0]); $txOrigin.val(accounts[0]);
} else $txOrigin.val('unknown'); } else $txOrigin.val('unknown');
} }
if (executionContext === 'vm') { if (executionContext === 'vm') {
dapp.getAccounts(renderAccounts); dapp.getAccounts(renderAccounts);
} else { } else {
web3.eth.getAccounts(renderAccounts); web3.eth.getAccounts(renderAccounts);
} }
$contractOutput.find('.title').click(function(ev){ $(this).closest('.contract').toggleClass('hide'); }); $contractOutput.find('.title').click(function(ev){ $(this).closest('.contract').toggleClass('hide'); });
$('#output').append( $contractOutput ); $('#output').append( $contractOutput );
$('.col2 input,textarea').click(function() { this.select(); }); $('.col2 input,textarea').click(function() { this.select(); });
}; };
var tableRowItems = function(first, second, cls) { var tableRowItems = function(first, second, cls) {
return $('<div class="crow"/>') return $('<div class="crow"/>')
.addClass(cls) .addClass(cls)
.append($('<div class="col1">').append(first)) .append($('<div class="col1">').append(first))
.append($('<div class="col2">').append(second)); .append($('<div class="col2">').append(second));
}; };
var tableRow = function(description, data) { var tableRow = function(description, data) {
return tableRowItems( return tableRowItems(
$('<span/>').text(description), $('<span/>').text(description),
$('<input readonly="readonly"/>').val(data)); $('<input readonly="readonly"/>').val(data));
}; };
var textRow = function(description, data, cls) { var textRow = function(description, data, cls) {
return tableRowItems( return tableRowItems(
$('<strong/>').text(description), $('<strong/>').text(description),
$('<textarea readonly="readonly" class="gethDeployText"/>').val(data), $('<textarea readonly="readonly" class="gethDeployText"/>').val(data),
cls); cls);
}; };
var getDetails = function(contract, source, contractName) { var getDetails = function(contract, source, contractName) {
var button = $('<button>Toggle Details</button>'); var button = $('<button>Toggle Details</button>');
var details = $('<div style="display: none;"/>') var details = $('<div style="display: none;"/>')
.append(tableRow('Solidity Interface', contract.solidity_interface)) .append(tableRow('Solidity Interface', contract.solidity_interface))
.append(tableRow('Opcodes', contract.opcodes)); .append(tableRow('Opcodes', contract.opcodes));
var funHashes = ''; var funHashes = '';
for (var fun in contract.functionHashes) for (var fun in contract.functionHashes)
funHashes += contract.functionHashes[fun] + ' ' + fun + '\n'; funHashes += contract.functionHashes[fun] + ' ' + fun + '\n';
details.append($('<span class="col1">Functions</span>')); details.append($('<span class="col1">Functions</span>'));
details.append($('<pre/>').text(funHashes)); details.append($('<pre/>').text(funHashes));
details.append($('<span class="col1">Gas Estimates</span>')); details.append($('<span class="col1">Gas Estimates</span>'));
details.append($('<pre/>').text(formatGasEstimates(contract.gasEstimates))); details.append($('<pre/>').text(formatGasEstimates(contract.gasEstimates)));
if (contract.runtimeBytecode && contract.runtimeBytecode.length > 0) if (contract.runtimeBytecode && contract.runtimeBytecode.length > 0)
details.append(tableRow('Runtime Bytecode', contract.runtimeBytecode)); details.append(tableRow('Runtime Bytecode', contract.runtimeBytecode));
if (contract.assembly !== null) if (contract.assembly !== null)
{ {
details.append($('<span class="col1">Assembly</span>')); details.append($('<span class="col1">Assembly</span>'));
var assembly = $('<pre/>').text(formatAssemblyText(contract.assembly, '', source)); var assembly = $('<pre/>').text(formatAssemblyText(contract.assembly, '', source));
details.append(assembly); details.append(assembly);
} }
button.click(function() { detailsOpen[contractName] = !detailsOpen[contractName]; details.toggle(); }); button.click(function() { detailsOpen[contractName] = !detailsOpen[contractName]; details.toggle(); });
if (detailsOpen[contractName]) if (detailsOpen[contractName])
details.show(); details.show();
return $('<div class="contractDetails"/>').append(button).append(details); return $('<div class="contractDetails"/>').append(button).append(details);
}; };
var formatGasEstimates = function(data) { var formatGasEstimates = function(data) {
var gasToText = function(g) { return g === null ? 'unknown' : g; } var gasToText = function(g) { return g === null ? 'unknown' : g; }
var text = ''; var text = '';
if ('creation' in data) if ('creation' in data)
text += 'Creation: ' + gasToText(data.creation[0]) + ' + ' + gasToText(data.creation[1]) + '\n'; text += 'Creation: ' + gasToText(data.creation[0]) + ' + ' + gasToText(data.creation[1]) + '\n';
text += 'External:\n'; text += 'External:\n';
for (var fun in data.external) for (var fun in data.external)
text += ' ' + fun + ': ' + gasToText(data.external[fun]) + '\n'; text += ' ' + fun + ': ' + gasToText(data.external[fun]) + '\n';
text += 'Internal:\n'; text += 'Internal:\n';
for (var fun in data.internal) for (var fun in data.internal)
text += ' ' + fun + ': ' + gasToText(data.internal[fun]) + '\n'; text += ' ' + fun + ': ' + gasToText(data.internal[fun]) + '\n';
return text; return text;
}; };
var formatAssemblyText = function(asm, prefix, source) { var formatAssemblyText = function(asm, prefix, source) {
if (typeof(asm) == typeof('') || asm === null || asm === undefined) if (typeof(asm) == typeof('') || asm === null || asm === undefined)
return prefix + asm + '\n'; return prefix + asm + '\n';
var text = prefix + '.code\n'; var text = prefix + '.code\n';
$.each(asm['.code'], function(i, item) { $.each(asm['.code'], function(i, item) {
var v = item.value === undefined ? '' : item.value; var v = item.value === undefined ? '' : item.value;
var src = ''; var src = '';
if (item.begin !== undefined && item.end != undefined) if (item.begin !== undefined && item.end != undefined)
src = source.slice(item.begin, item.end).replace('\n', '\\n', 'g'); src = source.slice(item.begin, item.end).replace('\n', '\\n', 'g');
if (src.length > 30) if (src.length > 30)
src = src.slice(0, 30) + '...'; src = src.slice(0, 30) + '...';
if (item.name != 'tag') if (item.name != 'tag')
text += ' '; text += ' ';
text += prefix + item.name + ' ' + v + '\t\t\t' + src + '\n'; text += prefix + item.name + ' ' + v + '\t\t\t' + src + '\n';
}); });
text += prefix + '.data\n'; text += prefix + '.data\n';
if (asm['.data']) if (asm['.data'])
$.each(asm['.data'], function(i, item) { $.each(asm['.data'], function(i, item) {
text += ' ' + prefix + '' + i + ':\n'; text += ' ' + prefix + '' + i + ':\n';
text += formatAssemblyText(item, prefix + ' ', source); text += formatAssemblyText(item, prefix + ' ', source);
}); });
return text; return text;
}; };
$('.asmOutput button').click(function() {$(this).parent().find('pre').toggle(); }); $('.asmOutput button').click(function() {$(this).parent().find('pre').toggle(); });
var getConstructorInterface = function(abi) { var getConstructorInterface = function(abi) {
var funABI = {'name':'','inputs':[],'type':'constructor','outputs':[]}; var funABI = {'name':'','inputs':[],'type':'constructor','outputs':[]};
for (var i = 0; i < abi.length; i++) for (var i = 0; i < abi.length; i++)
if (abi[i].type == 'constructor') { if (abi[i].type == 'constructor') {
funABI.inputs = abi[i].inputs || []; funABI.inputs = abi[i].inputs || [];
break; break;
} }
return funABI; return funABI;
}; };
syncStorage() syncStorage()
}); });
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment