Commit a8752918 authored by d11e9's avatar d11e9

fix indentation/whitespce in index.html

parent 24efa2e5
<html> <html>
<head> <head>
<meta charset="utf-8"> <meta charset="utf-8">
<!-- <!--
The MIT License (MIT) The MIT License (MIT)
Copyright (c) 2014, 2015, the individual contributors Copyright (c) 2014, 2015, the individual contributors
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions: furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software. all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE. THE SOFTWARE.
--> -->
<meta http-equiv="X-UA-Compatible" content="chrome=1"> <meta http-equiv="X-UA-Compatible" content="chrome=1">
<title>Solidity realtime compiler and runtime</title> <title>Solidity realtime compiler and runtime</title>
<link rel="stylesheet" href="assets/css/styles.css"> <link rel="stylesheet" href="assets/css/styles.css">
<link rel="stylesheet" href="assets/css/pygment_trac.css"> <link rel="stylesheet" href="assets/css/pygment_trac.css">
<link rel="stylesheet" href="assets/css/universal-dapp.css"> <link rel="stylesheet" href="assets/css/universal-dapp.css">
<link rel="stylesheet" href="assets/css/browser-solidity.css"> <link rel="stylesheet" href="assets/css/browser-solidity.css">
<link rel="stylesheet" href="assets/css/font-awesome.min.css"> <link rel="stylesheet" href="assets/css/font-awesome.min.css">
<meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=no"> <meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=no">
<style type="text/css">
<script src="bin/list.js"></script>
</style> <script src="assets/js/jquery-2.1.3.min.js"></script>
<script src="bin/list.js"></script> <script src="assets/js/ace.js"></script>
<script src="assets/js/jquery-2.1.3.min.js"></script> <script src="assets/js/mode-solidity.js"></script>
<script src="assets/js/ace.js"></script> <script src="bin/soljson-latest.js"></script>
<script src="assets/js/mode-solidity.js"></script> <script src="assets/js/ethereumjs-vm.js"></script>
<script src="bin/soljson-latest.js"></script> <script src="assets/js/universal-dapp.js"></script>
<script src="assets/js/ethereumjs-vm.js"></script> <script src="assets/js/web3.min.js"></script>
<script src="assets/js/universal-dapp.js"></script> <script src="assets/js/ballot.sol.js"></script>
<script src="assets/js/web3.min.js"></script>
<script src="assets/js/ballot.sol.js"></script> </head>
<body>
</head>
<body> <div id="editor">
<div id="files">
<span class="newFile" title="New File"><i class="fa fa-file-text-o"></i></span>
<div id="editor"> <span class="toggleRHP" title="Toggle right hand panel"><i class="fa fa-columns"></i></span>
<div id="files">
<span class="newFile" title="New File"><i class="fa fa-file-text-o"></i></span>
<span class="toggleRHP" title="Toggle right hand panel"><i class="fa fa-columns"></i></span>
</div>
<div id="input"></div>
<div id="dragbar"></div>
</div>
<div id="righthand-panel">
<div id="header">
<div id="menu">
<img id="solIcon" title="Solidity realtime compiler and runtime" src="assets/img/sol.svg" alt="Solidity realtime compiler and runtime">
<ul id="options">
<li class="txView active"><i class="fa fa-send"></i></li>
<li class="envView"><i class="fa fa-cube"></i></li>
<li class="publishView"><i class="fa fa-cloud-upload"></i></li>
<li class="settingsView"><i class="fa fa-gear"></i></li>
</ul>
</div> </div>
<div id="optionViews" class="txView"> <div id="input"></div>
<div id="txView"> <div id="dragbar"></div>
<div class="row"> </div>
<label for="txorigin"><select name="txorigin" id="txorigin"></select> Transaction origin</label>
</div> <div id="righthand-panel">
<div class="row hide"> <div id="header">
<label for="gas"><input type="number" id="gas" value="0"> Gas</label> <div id="menu">
<img id="solIcon" title="Solidity realtime compiler and runtime" src="assets/img/sol.svg" alt="Solidity realtime compiler and runtime">
<ul id="options">
<li class="txView active"><i class="fa fa-send"></i></li>
<li class="envView"><i class="fa fa-cube"></i></li>
<li class="publishView"><i class="fa fa-cloud-upload"></i></li>
<li class="settingsView"><i class="fa fa-gear"></i></li>
</ul>
</div>
<div id="optionViews" class="txView">
<div id="txView">
<div class="row">
<label for="txorigin"><select name="txorigin" id="txorigin"></select> Transaction origin</label>
</div>
<div class="row hide">
<label for="gas"><input type="number" id="gas" value="0"> Gas</label>
</div>
<div class="row hide">
<label for="gasPrice"><input type="number" id="gasPrice" value="0"> Gas Price</label>
</div>
<div class="row hide">
<label for="value"><input type="number" id="value" value="0"> Value</label>
</div>
</div> </div>
<div class="row hide"> <div id="settingsView">
<label for="gasPrice"><input type="number" id="gasPrice" value="0"> Gas Price</label> <div class="version row"><strong>Solidity version:</strong> <span id="version">(loading)</span></div>
<div class="row">Change to: <select id="versionSelector"></select></div>
<div class="row">
<label for="editorWrap"><input id="editorWrap" type="checkbox">Text Wrap</label>
<label for="optimize"><input id="optimize" type="checkbox">Enable Optimization</label>
</div>
</div> </div>
<div class="row hide"> <div id="publishView">
<label for="value"><input type="number" id="value" value="0"> Value</label> <p><button id="gist" title="Publish all files as public gist on github.com"><i class="fa fa-github"></i> Publish Gist</button> Publish all open files to an anonymous github gist.</p>
<p>You can also load a gist by adding the following <span class="pre">#gist=GIST_ID</span> to your url, where GIST_ID is the id of the gist to load.</p>
</div> </div>
</div> <div id="envView">
<div id="settingsView"> <span id="executionContext">
<div class="version row"><strong>Solidity version:</strong> <span id="version">(loading)</span></div> <label for="vm" title="Execution environment does not connect to any node, everything is local and in memory only.">
<div class="row">Change to: <select id="versionSelector"></select></div> <input id="vm" type="radio" value="vm" checked name="executionContext">
<div class="row"> JavaScript VM
<label for="editorWrap"><input id="editorWrap" type="checkbox">Text Wrap</label> </label>
<label for="optimize"><input id="optimize" type="checkbox">Enable Optimization</label> <label for="web3" title="Execution environment connects to node at localhost, transactions will be sent to the network and can cause loss of money or worse!">
<input id="web3" type="radio" value="web3" name="executionContext">
Web3 Provider
</label>
</span>
</div> </div>
</div> </div>
<div id="publishView">
<p><button id="gist" title="Publish all files as public gist on github.com"><i class="fa fa-github"></i> Publish Gist</button> Publish all open files to an anonymous github gist.</p>
<p>You can also load a gist by adding the following <span class="pre">#gist=GIST_ID</span> to your url, where GIST_ID is the id of the gist to load.</p>
</div>
<div id="envView">
<span id="executionContext">
<label for="vm" title="Execution environment does not connect to any node, everything is local and in memory only.">
<input id="vm" type="radio" value="vm" checked name="executionContext">
JavaScript VM
</label>
<label for="web3" title="Execution environment connects to node at localhost, transactions will be sent to the network and can cause loss of money or worse!">
<input id="web3" type="radio" value="web3" name="executionContext">
Web3 Provider
</label>
</span>
</div>
</div> </div>
<div id="output"></div>
</div> </div>
<div id="output"></div>
</div>
<script>
<script> $(document).ready(function() {
$(document).ready(function() { // ------------------ gist load ----------------
// ------------------ gist load ---------------- function getGistId(str) {
var idr = /[0-9A-Fa-f]{8,}/;
function getGistId(str) { var match = idr.exec(str)[0];
var idr = /[0-9A-Fa-f]{8,}/ return match;
var match = idr.exec(str)[0]
return match;
}
var location_hash_params = window.location.hash.substr(1).split("=");
var loadingFromGist = false;
if (location_hash_params.indexOf('gist') !== -1 && location_hash_params.length >= 2) {
var index = location_hash_params.indexOf('gist');
var gistId;
var key = location_hash_params[index+1];
if (key === '') {
var str = prompt("Enter the URL or ID of the Gist you'd like to load.")
if (str !== '') {
gistId = getGistId( str );
loadingFromGist = true;
} }
} else {
gistId = getGistId( key ); var location_hash_params = window.location.hash.substr(1).split("=");
loadingFromGist = true; var loadingFromGist = false;
} if (location_hash_params.indexOf('gist') !== -1 && location_hash_params.length >= 2) {
$.ajax({ var index = location_hash_params.indexOf('gist');
url: 'https://api.github.com/gists/'+gistId, var gistId;
jsonp: 'callback', var key = location_hash_params[index+1];
dataType: 'jsonp', if (key === '') {
success: function(response){ var str = prompt("Enter the URL or ID of the Gist you'd like to load.");
if (response.data) { if (str !== '') {
for(var f in response.data.files) { gistId = getGistId( str );
window.localStorage[fileKey(f)] = response.data.files[f].content; loadingFromGist = true;
} }
updateFiles(); } else {
gistId = getGistId( key );
loadingFromGist = true;
} }
$.ajax({
url: 'https://api.github.com/gists/'+gistId,
jsonp: 'callback',
dataType: 'jsonp',
success: function(response){
if (response.data) {
for(var f in response.data.files) {
window.localStorage[fileKey(f)] = response.data.files[f].content;
}
updateFiles();
}
}
});
} }
});
}
// ----------------- 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 session = editor.getSession(); var session = editor.getSession();
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]; SOL_CACHE_FILE = getFiles()[0];
editor.setValue( window.localStorage[SOL_CACHE_FILE], -1); editor.setValue( window.localStorage[SOL_CACHE_FILE], -1);
editor.resize(true); editor.resize(true);
session.setMode("ace/mode/javascript"); session.setMode("ace/mode/javascript");
session.setTabSize(4); session.setTabSize(4);
session.setUseSoftTabs(true); session.setUseSoftTabs(true);
// ----------------- tabbed menu ------------------- // ----------------- tabbed menu -------------------
$('#options li').click(function(ev){ $('#options li').click(function(ev){
var $el = $(this); var $el = $(this);
var cls = /[a-z]+View/.exec( $el.get(0).className )[0]; var cls = /[a-z]+View/.exec( $el.get(0).className )[0];
if (!$el.hasClass('active')) { if (!$el.hasClass('active')) {
$el.parent().find('li').removeClass('active'); $el.parent().find('li').removeClass('active');
$('#optionViews').attr('class', '').addClass(cls); $('#optionViews').attr('class', '').addClass(cls);
$el.addClass('active'); $el.addClass('active');
} else { } else {
$el.removeClass('active'); $el.removeClass('active');
$('#optionViews').removeClass(cls); $('#optionViews').removeClass(cls);
} }
}); });
// ----------------- execution context ------------- // ----------------- execution context -------------
var $vmToggle = $('#vm'); var $vmToggle = $('#vm');
var $web3Toggle = $('#web3'); var $web3Toggle = $('#web3');
var executionContext = 'vm'; var executionContext = 'vm';
$vmToggle.get(0).checked = true; $vmToggle.get(0).checked = true;
$vmToggle.on('change', executionContextChange ); $vmToggle.on('change', executionContextChange );
$web3Toggle.on('change', executionContextChange ); $web3Toggle.on('change', executionContextChange );
function executionContextChange (ev) { function executionContextChange (ev) {
if (ev.target.value == 'web3' && !confirm("Are you sure you want to connect to a local ethereum node?") ) { if (ev.target.value == 'web3' && !confirm("Are you sure you want to connect to a local ethereum node?") ) {
$vmToggle.get(0).checked = true; $vmToggle.get(0).checked = true;
executionContext = 'vm'; executionContext = 'vm';
} else executionContext = ev.target.value; } else executionContext = ev.target.value;
compile(); compile();
} }
// ------------------ gist publish -------------- // ------------------ gist publish --------------
$('#gist').click(function(){ $('#gist').click(function(){
if (confirm("Are you sure you want to publish all your files anonymously as a public gist on github.com")) { 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();
var description = "Created using soleditor: Realtime Ethereum Contract Compiler and Runtime. Load this file by pasting this gists URL or ID at https://chriseth.github.io/browser-solidity#gist="; var description = "Created using soleditor: Realtime Ethereum Contract Compiler and Runtime. Load this file by pasting this gists URL or ID at https://chriseth.github.io/browser-solidity#gist=";
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-------------
var $filesEl = $('#files');
$filesEl.on('click','.newFile', function() {
while (window.localStorage[SOL_CACHE_UNTITLED + untitledCount])
untitledCount = (untitledCount - 0) + 1;
SOL_CACHE_FILE = SOL_CACHE_UNTITLED + untitledCount;
window.localStorage[SOL_CACHE_FILE] = '';
updateFiles();
})
$filesEl.on('click', '.file:not(.active)', showFileHandler);
$filesEl.on('click', '.file.active', function(ev) {
var $fileTabEl = $(this);
var originalName = $fileTabEl.find('.name').text();
ev.preventDefault();
if ($(this).find('input').length > 0) return false;
var $fileNameInputEl = $('<input value="'+originalName+'"/>');
$fileTabEl.html($fileNameInputEl);
$fileNameInputEl.focus();
$fileNameInputEl.select();
$fileNameInputEl.on('blur', handleRename);
$fileNameInputEl.keyup(handleRename);
function handleRename(ev) {
ev.preventDefault();
if (ev.which && ev.which !== 13) return false;
var newName = ev.target.value;
$fileNameInputEl.off('blur');
$fileNameInputEl.off('keyup');
if (newName !== originalName && confirm("Are you sure you want to rename: " + originalName + " to " + newName + '?')) {
var content = window.localStorage.getItem( fileKey(originalName) );
window.localStorage[fileKey( newName )] = content;
window.localStorage.removeItem( fileKey( originalName) );
SOL_CACHE_FILE = fileKey( newName );
}
updateFiles();
return false;
}
return false; // ----------------- file selector-------------
}) var $filesEl = $('#files');
$filesEl.on('click','.newFile', function() {
while (window.localStorage[SOL_CACHE_UNTITLED + untitledCount])
untitledCount = (untitledCount - 0) + 1;
SOL_CACHE_FILE = SOL_CACHE_UNTITLED + untitledCount;
window.localStorage[SOL_CACHE_FILE] = '';
updateFiles();
});
$filesEl.on('click', '.file .remove', function(ev) { $filesEl.on('click', '.file:not(.active)', showFileHandler);
ev.preventDefault();
var name = $(this).parent().find('.name').text(); $filesEl.on('click', '.file.active', function(ev) {
var index = getFiles().indexOf( fileKey(name) ); var $fileTabEl = $(this);
var originalName = $fileTabEl.find('.name').text();
ev.preventDefault();
if ($(this).find('input').length > 0) return false;
var $fileNameInputEl = $('<input value="'+originalName+'"/>');
$fileTabEl.html($fileNameInputEl);
$fileNameInputEl.focus();
$fileNameInputEl.select();
$fileNameInputEl.on('blur', handleRename);
$fileNameInputEl.keyup(handleRename);
function handleRename(ev) {
ev.preventDefault();
if (ev.which && ev.which !== 13) return false;
var newName = ev.target.value;
$fileNameInputEl.off('blur');
$fileNameInputEl.off('keyup');
if (newName !== originalName && confirm("Are you sure you want to rename: " + originalName + " to " + newName + '?')) {
var content = window.localStorage.getItem( fileKey(originalName) );
window.localStorage[fileKey( newName )] = content;
window.localStorage.removeItem( fileKey( originalName) );
SOL_CACHE_FILE = fileKey( newName );
}
if (confirm("Are you sure you want to remove: " + name + " from local storage?")) { updateFiles();
window.localStorage.removeItem( fileKey( name ) ); return false;
SOL_CACHE_FILE = getFiles()[ Math.max(0, index - 1)]; }
updateFiles();
}
return false;
});
function showFileHandler(ev) { return false;
ev.preventDefault(); })
SOL_CACHE_FILE = fileKey( $(this).find('.name').text() );
updateFiles();
return false;
}
function fileTabFromKey(key) { $filesEl.on('click', '.file .remove', function(ev) {
var name = fileNameFromKey(key); ev.preventDefault();
return $('#files .file').filter(function(){ return $(this).find('.name').text() == name; }); var name = $(this).parent().find('.name').text();
} var index = getFiles().indexOf( fileKey(name) );
if (confirm("Are you sure you want to remove: " + name + " from local storage?")) {
window.localStorage.removeItem( fileKey( name ) );
SOL_CACHE_FILE = getFiles()[ Math.max(0, index - 1)];
updateFiles();
}
return false;
});
function updateFiles() { function showFileHandler(ev) {
var $filesEl = $('#files'); ev.preventDefault();
var files = getFiles(); SOL_CACHE_FILE = fileKey( $(this).find('.name').text() );
updateFiles();
return false;
}
$filesEl.find('.file').remove(); function fileTabFromKey(key) {
var name = fileNameFromKey(key);
return $('#files .file').filter(function(){ return $(this).find('.name').text() == name; });
}
for (var f in files) {
$filesEl.append(fileTabTemplate(files[f])); function updateFiles() {
} var $filesEl = $('#files');
var files = getFiles();
if (SOL_CACHE_FILE) {
var active = fileTabFromKey(SOL_CACHE_FILE); $filesEl.find('.file').remove();
active.addClass('active');
editor.setValue( window.localStorage[SOL_CACHE_FILE] || '', -1); for (var f in files) {
editor.focus(); $filesEl.append(fileTabTemplate(files[f]));
} }
$('#input').toggle( !!SOL_CACHE_FILE );
$('#output').toggle( !!SOL_CACHE_FILE ); if (SOL_CACHE_FILE) {
} var active = fileTabFromKey(SOL_CACHE_FILE);
active.addClass('active');
function fileTabTemplate(key) { editor.setValue( window.localStorage[SOL_CACHE_FILE] || '', -1);
var name = fileNameFromKey(key); editor.focus();
return $('<span class="file"><span class="name">'+name+'</span><span class="remove"><i class="fa fa-close"></i></span></span>'); }
} $('#input').toggle( !!SOL_CACHE_FILE );
$('#output').toggle( !!SOL_CACHE_FILE );
function fileKey( name ) {
return SOL_CACHE_FILE_PREFIX + name;
}
function fileNameFromKey(key) {
return key.replace( SOL_CACHE_FILE_PREFIX, '' );
}
function getFiles() {
var files = [];
for (var f in localStorage ) {
if (f.indexOf( SOL_CACHE_FILE_PREFIX, 0 ) === 0) {
files.push(f);
} }
}
return files;
}
updateFiles(); function fileTabTemplate(key) {
var name = fileNameFromKey(key);
return $('<span class="file"><span class="name">'+name+'</span><span class="remove"><i class="fa fa-close"></i></span></span>');
}
// ----------------- version selector------------- function fileKey( name ) {
return SOL_CACHE_FILE_PREFIX + name;
}
// var soljsonSources is provided by bin/list.js function fileNameFromKey(key) {
$('option', '#versionSelector').remove(); return key.replace( SOL_CACHE_FILE_PREFIX, '' );
$.each(soljsonSources, function(i, file) {
if (file) {
var version = file.replace(/soljson-(.*).js/, "$1");
$('#versionSelector').append(new Option(version, file));
} }
});
$('#versionSelector').change(function() { function getFiles() {
Module = null; var files = [];
compileJSON = null; for (var f in localStorage ) {
var script = document.createElement('script'); if (f.indexOf( SOL_CACHE_FILE_PREFIX, 0 ) === 0) {
script.type = 'text/javascript'; files.push(f);
script.src = 'bin/' + $('#versionSelector').val(); }
$('head').append(script); }
onCompilerLoaded(); return files;
}); }
// ----------------- resizeable ui --------------- updateFiles();
var EDITOR_SIZE_CACHE_KEY = "editor-size-cache"; // ----------------- version selector-------------
var dragging = false;
$('#dragbar').mousedown(function(e){ // var soljsonSources is provided by bin/list.js
e.preventDefault(); $('option', '#versionSelector').remove();
dragging = true; $.each(soljsonSources, function(i, file) {
var main = $('#righthand-panel'); if (file) {
var ghostbar = $('<div id="ghostbar">', { var version = file.replace(/soljson-(.*).js/, "$1");
css: { $('#versionSelector').append(new Option(version, file));
top: main.offset().top,
left: main.offset().left
} }
}).prependTo('body'); });
$('#versionSelector').change(function() {
Module = null;
compileJSON = null;
var script = document.createElement('script');
script.type = 'text/javascript';
script.src = 'bin/' + $('#versionSelector').val();
$('head').append(script);
onCompilerLoaded();
});
// ----------------- resizeable ui ---------------
var EDITOR_SIZE_CACHE_KEY = "editor-size-cache";
var dragging = false;
$('#dragbar').mousedown(function(e){
e.preventDefault();
dragging = true;
var main = $('#righthand-panel');
var ghostbar = $('<div id="ghostbar">', {
css: {
top: main.offset().top,
left: main.offset().left
}
}).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(){
window.localStorage[EDITOR_SIZE_CACHE_KEY] = $('#righthand-panel').width();
}
$(document).mouseup(function(e){
if (dragging) {
var delta = $body.width() - e.pageX+2;
$('#ghostbar').remove();
$(document).unbind('mousemove');
dragging = false;
setEditorSize(delta);
window.localStorage.setItem(EDITOR_SIZE_CACHE_KEY, delta);
} }
});
// set cached defaults function getEditorSize(){
var cachedSize = window.localStorage.getItem(EDITOR_SIZE_CACHE_KEY); window.localStorage[EDITOR_SIZE_CACHE_KEY] = $('#righthand-panel').width();
if (cachedSize) setEditorSize(cachedSize); }
else getEditorSize();
$(document).mouseup(function(e){
if (dragging) {
var delta = $body.width() - e.pageX+2;
$('#ghostbar').remove();
$(document).unbind('mousemove');
dragging = false;
setEditorSize(delta);
window.localStorage.setItem(EDITOR_SIZE_CACHE_KEY, delta);
}
});
// ----------------- toggle right hand panel // set cached defaults
var cachedSize = window.localStorage.getItem(EDITOR_SIZE_CACHE_KEY);
if (cachedSize) setEditorSize(cachedSize);
else getEditorSize();
var toggledRHP = false;
$('.toggleRHP').click(function(){
toggledRHP = !toggledRHP;
setEditorSize( toggledRHP ? 0 : window.localStorage[EDITOR_SIZE_CACHE_KEY] );
$('.toggleRHP').toggleClass('toggled', toggledRHP)
});
// ----------------- editor resize --------------- // ----------------- toggle right hand panel -----------------
function onResize() { var toggledRHP = false;
editor.resize(); $('.toggleRHP').click(function(){
session.setUseWrapMode(document.querySelector('#editorWrap').checked); toggledRHP = !toggledRHP;
if(session.getUseWrapMode()) { setEditorSize( toggledRHP ? 0 : window.localStorage[EDITOR_SIZE_CACHE_KEY] );
var characterWidth = editor.renderer.characterWidth; $('.toggleRHP').toggleClass('toggled', toggledRHP)
var contentWidth = editor.container.ownerDocument.getElementsByClassName("ace_scroller")[0].clientWidth; });
if(contentWidth > 0) { // ----------------- editor resize ---------------
session.setWrapLimit(parseInt(contentWidth / characterWidth, 10));
function onResize() {
editor.resize();
session.setUseWrapMode(document.querySelector('#editorWrap').checked);
if(session.getUseWrapMode()) {
var characterWidth = editor.renderer.characterWidth;
var contentWidth = editor.container.ownerDocument.getElementsByClassName("ace_scroller")[0].clientWidth;
if(contentWidth > 0) {
session.setWrapLimit(parseInt(contentWidth / characterWidth, 10));
}
} }
} }
} 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 previousInput = ''; var previousInput = '';
var sourceAnnotations = []; var sourceAnnotations = [];
var compile = function() { var compile = function() {
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 inputIncludingImports = includeLocalImports(input); var inputIncludingImports = includeLocalImports(input);
var optimize = document.querySelector('#optimize').checked; var optimize = document.querySelector('#optimize').checked;
try { try {
var data = $.parseJSON(compileJSON(inputIncludingImports, optimize ? 1 : 0)); var data = $.parseJSON(compileJSON(inputIncludingImports, optimize ? 1 : 0));
} catch (exception) { } catch (exception) {
renderError("Uncaught JavaScript Exception:\n" + exception); renderError("Uncaught JavaScript Exception:\n" + exception);
return; return;
} }
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 (noFatalErrors) renderContracts(data, input);
} }
if (noFatalErrors) renderContracts(data, input); var compileTimeout = null;
var onChange = function() {
} var input = editor.getValue();
if (input === "") {
var compileTimeout = null; window.localStorage.setItem(SOL_CACHE_FILE, '');
var onChange = function() { return;
var input = editor.getValue(); }
if (input === "") { if (input === previousInput)
window.localStorage.setItem(SOL_CACHE_FILE, ''); return;
return; previousInput = input;
if (compileTimeout) window.clearTimeout(compileTimeout);
compileTimeout = window.setTimeout(compile, 300);
};
var onCompilerLoaded = function() {
compileJSON = Module.cwrap("compileJSON", "string", ["string", "number"]);
$('#version').text(Module.cwrap("version", "string", [])());
previousInput = '';
onChange();
};
function includeLocalImports(input) {
var importRegex = /import\s[\'\"]([^\'\"]+)[\'\"];/g;
var imports = [];
var matches = [];
var match;
while ((match = importRegex.exec(input)) !== null) {
if (match[1] && getFiles().indexOf(fileKey(match[1])) !== -1) {
imports.push(match[1]);
matches.push(match[0]);
}
}
for (var i in imports) {
imported = includeLocalImports(window.localStorage.getItem( fileKey(imports[i]) ));
input = input.replace(matches[i], imported);
}
return input;
} }
if (input === previousInput)
return; if (Module)
previousInput = input; onCompilerLoaded();
if (compileTimeout) window.clearTimeout(compileTimeout);
compileTimeout = window.setTimeout(compile, 300); editor.getSession().on('change', onChange);
};
document.querySelector('#optimize').addEventListener('change', compile);
var onCompilerLoaded = function() {
compileJSON = Module.cwrap("compileJSON", "string", ["string", "number"]); // ----------------- compiler output renderer ----------------------
$('#version').text(Module.cwrap("version", "string", [])()); var detailsOpen = {};
previousInput = '';
onChange(); function errortype(message) {
}; return message.match(/^[0-9:]* Warning: /) ? 'warning' : 'error';
function includeLocalImports(input) {
var importRegex = /import\s[\'\"]([^\'\"]+)[\'\"];/g;
var imports = [];
var matches = [];
var match;
while ((match = importRegex.exec(input)) !== null) {
if (match[1] && getFiles().indexOf(fileKey(match[1])) !== -1) {
imports.push(match[1]);
matches.push(match[0]);
}
}
for (var i in imports) {
imported = includeLocalImports(window.localStorage.getItem( fileKey(imports[i]) ));
input = input.replace(matches[i], imported);
}
return input;
}
if (Module)
onCompilerLoaded();
editor.getSession().on('change', onChange);
document.querySelector('#optimize').addEventListener('change', compile);
// ----------------- compiler output renderer ----------------------
var detailsOpen = {};
function errortype(message) {
return message.match(/^[0-9:]* Warning: /) ? 'warning' : 'error';
}
var renderError = function(message) {
var type = errortype(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);
$('#output').append( $error );
var err = message.match(/^:([0-9]*):([0-9]*)/);
if (err && err.length) {
var errLine = parseInt(err[1], 10) - 1;
var errCol = err[2] ? parseInt(err[2], 10) : 0;
sourceAnnotations[sourceAnnotations.length] = {
row: errLine,
column: errCol,
text: message,
type: type
};
editor.getSession().setAnnotations(sourceAnnotations);
$error.click(function(ev){
editor.focus();
editor.gotoLine(errLine + 1, errCol - 1, true);
});
$error.find('.close').click(function(ev){
ev.preventDefault();
$error.remove();
return false;
});
} }
};
var gethDeploy = function(contractName, interface, bytecode){ var renderError = function(message) {
var code = ""; var type = errortype(message);
var funABI = getConstructorInterface($.parseJSON(interface)); var $pre = $("<pre />").text(message);
var $error = $('<div class="sol ' + type + '"><div class="close"><i class="fa fa-close"></i></div></div>').prepend($pre);
$('#output').append( $error );
var err = message.match(/^:([0-9]*):([0-9]*)/);
if (err && err.length) {
var errLine = parseInt(err[1], 10) - 1;
var errCol = err[2] ? parseInt(err[2], 10) : 0;
sourceAnnotations[sourceAnnotations.length] = {
row: errLine,
column: errCol,
text: message,
type: type
};
editor.getSession().setAnnotations(sourceAnnotations);
$error.click(function(ev){
editor.focus();
editor.gotoLine(errLine + 1, errCol - 1, true);
});
$error.find('.close').click(function(ev){
ev.preventDefault();
$error.remove();
return false;
});
}
};
$.each(funABI.inputs, function(i, inp) { var gethDeploy = function(contractName, interface, bytecode){
code += "var " + inp.name + " = /* var of type " + inp.type + " here */ ;\n"; var code = "";
}); var funABI = getConstructorInterface($.parseJSON(interface));
code += "var " + contractName + "Contract = web3.eth.contract(" + interface.replace("\n","") + ");" $.each(funABI.inputs, function(i, inp) {
+"\nvar " + contractName + " = " + contractName + "Contract.new("; code += "var " + inp.name + " = /* var of type " + inp.type + " here */ ;\n";
$.each(funABI.inputs, function(i, inp) {
code += "\n " + inp.name + ",";
});
code += "\n {"+
"\n from: web3.eth.accounts[0], "+
"\n data: '"+bytecode+"', "+
"\n gas: 3000000"+
"\n }, function(e, contract){"+
"\n if (typeof contract.address != 'undefined') {"+
"\n console.log(e, contract);"+
"\n console.log('Contract mined! address: ' + contract.address + ' transactionHash: ' + contract.transactionHash);" +
"\n }" +
"\n })";
return code;
};
var combined = function(contractName, interface, bytecode){
return JSON.stringify([{name: contractName, interface: interface, bytecode: bytecode}]);
};
var renderContracts = function(data, source) {
var udappContracts = [];
for (var contractName in data.contracts) {
var contract = data.contracts[contractName];
udappContracts.push({
name: contractName,
interface: contract['interface'],
bytecode: contract.bytecode
}); });
}
var dapp = new UniversalDApp(udappContracts, { code += "var " + contractName + "Contract = web3.eth.contract(" + interface.replace("\n","") + ");"
vm: executionContext === 'vm', +"\nvar " + contractName + " = " + contractName + "Contract.new(";
removable: false,
getAddress: function(){ return $('txorigin').val(); }, $.each(funABI.inputs, function(i, inp) {
removable_instances: true, code += "\n " + inp.name + ",";
renderOutputModifier: function(contractName, $contractOutput) { });
code += "\n {"+
"\n from: web3.eth.accounts[0], "+
"\n data: '"+bytecode+"', "+
"\n gas: 3000000"+
"\n }, function(e, contract){"+
"\n if (typeof contract.address != 'undefined') {"+
"\n console.log(e, contract);"+
"\n console.log('Contract mined! address: ' + contract.address + ' transactionHash: ' + contract.transactionHash);" +
"\n }" +
"\n })";
return code;
};
var combined = function(contractName, interface, bytecode){
return JSON.stringify([{name: contractName, interface: interface, bytecode: bytecode}]);
};
var renderContracts = function(data, source) {
var udappContracts = [];
for (var contractName in data.contracts) {
var contract = data.contracts[contractName]; var contract = data.contracts[contractName];
return $contractOutput udappContracts.push({
.append(textRow('Bytecode', contract.bytecode)) name: contractName,
.append(textRow('Interface', contract['interface'])) interface: contract['interface'],
.append(textRow('Web3 deploy', gethDeploy(contractName.toLowerCase(),contract['interface'],contract.bytecode), 'deploy')) bytecode: contract.bytecode
.append(textRow('uDApp', combined(contractName,contract['interface'],contract.bytecode), 'deploy')) });
.append(getDetails(contract, source, contractName)); }
}}); var dapp = new UniversalDApp(udappContracts, {
var $contractOutput = dapp.render(); vm: executionContext === 'vm',
removable: false,
getAddress: function(){ return $('txorigin').val(); },
$txOrigin = $('#txorigin'); removable_instances: true,
if (executionContext === 'vm') { renderOutputModifier: function(contractName, $contractOutput) {
$txOrigin.empty(); var contract = data.contracts[contractName];
var addr = '0x' + dapp.address.toString('hex'); return $contractOutput
$txOrigin.val(addr); .append(textRow('Bytecode', contract.bytecode))
$txOrigin.append($('<option />').val(addr).text(addr)); .append(textRow('Interface', contract['interface']))
} else web3.eth.getAccounts(function(err, accounts) { .append(textRow('Web3 deploy', gethDeploy(contractName.toLowerCase(),contract['interface'],contract.bytecode), 'deploy'))
if (err) .append(textRow('uDApp', combined(contractName,contract['interface'],contract.bytecode), 'deploy'))
renderError(err.message); .append(getDetails(contract, source, contractName));
if (accounts && accounts[0]){ }});
var $contractOutput = dapp.render();
$txOrigin = $('#txorigin');
if (executionContext === 'vm') {
$txOrigin.empty(); $txOrigin.empty();
for( var a in accounts) { $txOrigin.append($('<option />').val(accounts[a]).text(accounts[a])); } var addr = '0x' + dapp.address.toString('hex');
$txOrigin.val(accounts[0]); $txOrigin.val(addr);
} else $txOrigin.val('unknown'); $txOrigin.append($('<option />').val(addr).text(addr));
}); } else web3.eth.getAccounts(function(err, accounts) {
if (err)
$contractOutput.find('.title').click(function(ev){ $(this).closest('.contract').toggleClass('hide'); }); renderError(err.message);
$('#output').append( $contractOutput ); if (accounts && accounts[0]){
$('.col2 input,textarea').click(function() { this.select(); }); $txOrigin.empty();
}; for( var a in accounts) { $txOrigin.append($('<option />').val(accounts[a]).text(accounts[a])); }
var tableRowItems = function(first, second, cls) { $txOrigin.val(accounts[0]);
return $('<div class="row"/>') } else $txOrigin.val('unknown');
.addClass(cls)
.append($('<div class="col1">').append(first))
.append($('<div class="col2">').append(second));
};
var tableRow = function(description, data) {
return tableRowItems(
$('<span/>').text(description),
$('<input readonly="readonly"/>').val(data));
};
var textRow = function(description, data, cls) {
return tableRowItems(
$('<strong/>').text(description),
$('<textarea readonly="readonly" class="gethDeployText"/>').val(data),
cls);
};
var getDetails = function(contract, source, contractName) {
var button = $('<button>Toggle Details</button>');
var details = $('<div style="display: none;"/>')
.append(tableRow('Solidity Interface', contract.solidity_interface))
.append(tableRow('Opcodes', contract.opcodes));
var funHashes = '';
for (var fun in contract.functionHashes)
funHashes += contract.functionHashes[fun] + ' ' + fun + '\n';
details.append($('<span class="col1">Functions</span>'));
details.append($('<pre/>').text(funHashes));
details.append($('<span class="col1">Gas Estimates</span>'));
details.append($('<pre/>').text(formatGasEstimates(contract.gasEstimates)));
if (contract.runtimeBytecode && contract.runtimeBytecode.length > 0)
details.append(tableRow('Runtime Bytecode', contract.runtimeBytecode));
if (contract.assembly !== null)
{
details.append($('<span class="col1">Assembly</span>'));
var assembly = $('<pre/>').text(formatAssemblyText(contract.assembly, '', source));
details.append(assembly);
}
button.click(function() { detailsOpen[contractName] = !detailsOpen[contractName]; details.toggle(); });
if (detailsOpen[contractName])
details.show();
return $('<div class="contractDetails"/>').append(button).append(details);
};
var formatGasEstimates = function(data) {
var gasToText = function(g) { return g === null ? 'unknown' : g; }
var text = '';
if ('creation' in data)
text += 'Creation: ' + gasToText(data.creation[0]) + ' + ' + gasToText(data.creation[1]) + '\n';
text += 'External:\n';
for (var fun in data.external)
text += ' ' + fun + ': ' + gasToText(data.external[fun]) + '\n';
text += 'Internal:\n';
for (var fun in data.internal)
text += ' ' + fun + ': ' + gasToText(data.internal[fun]) + '\n';
return text;
};
var formatAssemblyText = function(asm, prefix, source) {
if (typeof(asm) == typeof('') || asm === null || asm === undefined)
return prefix + asm + '\n';
var text = prefix + '.code\n';
$.each(asm['.code'], function(i, item) {
var v = item.value === undefined ? '' : item.value;
var src = '';
if (item.begin !== undefined && item.end != undefined)
src = source.slice(item.begin, item.end).replace('\n', '\\n', 'g');
if (src.length > 30)
src = src.slice(0, 30) + '...';
if (item.name != 'tag')
text += ' ';
text += prefix + item.name + ' ' + v + '\t\t\t' + src + '\n';
});
text += prefix + '.data\n';
if (asm['.data'])
$.each(asm['.data'], function(i, item) {
text += ' ' + prefix + '' + i + ':\n';
text += formatAssemblyText(item, prefix + ' ', source);
}); });
return text; $contractOutput.find('.title').click(function(ev){ $(this).closest('.contract').toggleClass('hide'); });
}; $('#output').append( $contractOutput );
$('.col2 input,textarea').click(function() { this.select(); });
$('.asmOutput button').click(function() {$(this).parent().find('pre').toggle(); }); };
var tableRowItems = function(first, second, cls) {
var getConstructorInterface = function(abi) { return $('<div class="row"/>')
var funABI = {'name':'','inputs':[],'type':'constructor','outputs':[]}; .addClass(cls)
for (var i = 0; i < abi.length; i++) .append($('<div class="col1">').append(first))
if (abi[i].type == 'constructor') { .append($('<div class="col2">').append(second));
funABI.inputs = abi[i].inputs || []; };
break; var tableRow = function(description, data) {
return tableRowItems(
$('<span/>').text(description),
$('<input readonly="readonly"/>').val(data));
};
var textRow = function(description, data, cls) {
return tableRowItems(
$('<strong/>').text(description),
$('<textarea readonly="readonly" class="gethDeployText"/>').val(data),
cls);
};
var getDetails = function(contract, source, contractName) {
var button = $('<button>Toggle Details</button>');
var details = $('<div style="display: none;"/>')
.append(tableRow('Solidity Interface', contract.solidity_interface))
.append(tableRow('Opcodes', contract.opcodes));
var funHashes = '';
for (var fun in contract.functionHashes)
funHashes += contract.functionHashes[fun] + ' ' + fun + '\n';
details.append($('<span class="col1">Functions</span>'));
details.append($('<pre/>').text(funHashes));
details.append($('<span class="col1">Gas Estimates</span>'));
details.append($('<pre/>').text(formatGasEstimates(contract.gasEstimates)));
if (contract.runtimeBytecode && contract.runtimeBytecode.length > 0)
details.append(tableRow('Runtime Bytecode', contract.runtimeBytecode));
if (contract.assembly !== null)
{
details.append($('<span class="col1">Assembly</span>'));
var assembly = $('<pre/>').text(formatAssemblyText(contract.assembly, '', source));
details.append(assembly);
} }
return funABI; button.click(function() { detailsOpen[contractName] = !detailsOpen[contractName]; details.toggle(); });
}; if (detailsOpen[contractName])
details.show();
return $('<div class="contractDetails"/>').append(button).append(details);
};
var formatGasEstimates = function(data) {
var gasToText = function(g) { return g === null ? 'unknown' : g; }
var text = '';
if ('creation' in data)
text += 'Creation: ' + gasToText(data.creation[0]) + ' + ' + gasToText(data.creation[1]) + '\n';
text += 'External:\n';
for (var fun in data.external)
text += ' ' + fun + ': ' + gasToText(data.external[fun]) + '\n';
text += 'Internal:\n';
for (var fun in data.internal)
text += ' ' + fun + ': ' + gasToText(data.internal[fun]) + '\n';
return text;
};
var formatAssemblyText = function(asm, prefix, source) {
if (typeof(asm) == typeof('') || asm === null || asm === undefined)
return prefix + asm + '\n';
var text = prefix + '.code\n';
$.each(asm['.code'], function(i, item) {
var v = item.value === undefined ? '' : item.value;
var src = '';
if (item.begin !== undefined && item.end != undefined)
src = source.slice(item.begin, item.end).replace('\n', '\\n', 'g');
if (src.length > 30)
src = src.slice(0, 30) + '...';
if (item.name != 'tag')
text += ' ';
text += prefix + item.name + ' ' + v + '\t\t\t' + src + '\n';
});
text += prefix + '.data\n';
if (asm['.data'])
$.each(asm['.data'], function(i, item) {
text += ' ' + prefix + '' + i + ':\n';
text += formatAssemblyText(item, prefix + ' ', source);
});
return text;
};
$('.asmOutput button').click(function() {$(this).parent().find('pre').toggle(); });
var getConstructorInterface = function(abi) {
var funABI = {'name':'','inputs':[],'type':'constructor','outputs':[]};
for (var i = 0; i < abi.length; i++)
if (abi[i].type == 'constructor') {
funABI.inputs = abi[i].inputs || [];
break;
}
return funABI;
};
}); });
</script> </script>
</body> </body>
</html> </html>
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