diff --git a/src/app.js b/src/app.js index f4d11ba38f..3018ecc870 100644 --- a/src/app.js +++ b/src/app.js @@ -1,8 +1,13 @@ var $ = require('jquery'); -var UniversalDApp = require('./universal-dapp.js'); var web3 = require('./web3-adapter.js'); -var ace = require('brace'); -require('./mode-solidity.js'); + +var utils = require('./app/utils'); +var queryParams = require('./app/query-params'); +var gistHandler = require('./app/gist-handler'); + +var StorageHandler = require('./app/storage-handler'); +var Editor = require('./app/editor'); +var Compiler = require('./app/compiler'); // The event listener needs to be registered as early as possible, because the // parent will send the message upon the "load" event. @@ -14,64 +19,11 @@ window.addEventListener("message", function(ev) { } }, false); -var Base64 = require('js-base64').Base64; - var run = function() { - // ------------------ query params (hash) ---------------- - - function getQueryParams() { - - var qs = window.location.hash.substr(1); - - if (window.location.search.length > 0) { - // use legacy query params instead of hash - window.location.hash = window.location.search.substr(1); - window.location.search = ""; - } - - var params = {}; - var parts = qs.split("&"); - for (var x in parts) { - var keyValue = parts[x].split("="); - if (keyValue[0] !== "") params[keyValue[0]] = keyValue[1]; - } - return params; - } - - function updateQueryParams(params) { - var currentParams = getQueryParams(); - var keys = Object.keys(params); - for (var x in keys) { - currentParams[keys[x]] = params[keys[x]]; - } - var queryString = "#"; - var updatedKeys = Object.keys(currentParams); - for( var y in updatedKeys) { - queryString += updatedKeys[y] + "=" + currentParams[updatedKeys[y]] + "&"; - } - window.location.hash = queryString.slice(0, -1); - } - - - function syncQueryParams() { - $('#optimize').attr( 'checked', (getQueryParams().optimize == "true") ); - } - - - window.onhashchange = syncQueryParams; - syncQueryParams(); - - // ------------------ gist load ---------------- - - function getGistId(str) { - var idr = /[0-9A-Fa-f]{8,}/; - var match = idr.exec(str); - return match ? match[0] : null; - } function loadFiles(files) { for (var f in files) { - var key = fileKey(f); + var key = utils.fileKey(f); var content = files[f].content; if (key in window.localStorage && window.localStorage[key] != content) { var count = ''; @@ -81,134 +33,58 @@ var run = function() { } window.localStorage[key] = content; } - SOL_CACHE_FILE = fileKey(Object.keys(files)[0]); + editor.setCacheFile(Object.keys(files)[0]); updateFiles(); } - var queryParams = getQueryParams(); - var loadingFromGist = false; - if (typeof queryParams['gist'] != undefined) { - var gistId; - if (queryParams['gist'] === '') { - var str = prompt("Enter the URL or ID of the Gist you would like to load."); - if (str !== '') { - gistId = getGistId( str ); - loadingFromGist = !!gistId; - } - } else { - gistId = queryParams['gist']; - loadingFromGist = !!gistId; - } - if (loadingFromGist) $.ajax({ - url: 'https://api.github.com/gists/'+gistId, - jsonp: 'callback', - dataType: 'jsonp', - success: function(response){ - if (response.data) { - if (!response.data.files) { - alert( "Gist load error: " + response.data.message ); - return; - } - loadFiles(response.data.files); - } - } - }); - } - loadFilesCallback = function(files) { loadFiles(files); }; + if (filesToLoad !== null) loadFiles(filesToLoad); - // ----------------- storage -------------------- - - function syncStorage() { - - if (typeof chrome === 'undefined' || !chrome || !chrome.storage || !chrome.storage.sync) return; - - var obj = {}; - var done = false; - var count = 0; - var dont = 0; - - function check(key){ - chrome.storage.sync.get( key, function(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.")) { - console.log("Overwriting", key ); - localStorage.setItem( key, resp[key] ); - updateFiles(); - } else { - console.log( "add to obj", obj, key); - obj[key] = localStorage[key]; - } - done++; - if (done >= count) chrome.storage.sync.set( obj, function(){ - console.log( "updated cloud files with: ", obj, this, arguments); - }); - }); - } - - for (var y in window.localStorage) { - console.log("checking", y); - obj[y] = window.localStorage.getItem(y); - if (y.indexOf(SOL_CACHE_FILE_PREFIX) !== 0) continue; - count++; - check(y); - } + // ------------------ query params (hash) ---------------- + function syncQueryParams() { + $('#optimize').attr( 'checked', (queryParams.get().optimize == "true") ); } - window.syncStorage = syncStorage; - syncStorage(); - + window.onhashchange = syncQueryParams; + syncQueryParams(); - // ----------------- editor ---------------------- + // ------------------ gist load ---------------- - var SOL_CACHE_FILE_PREFIX = 'sol-cache-file-'; - var SOL_CACHE_UNTITLED = SOL_CACHE_FILE_PREFIX + 'Untitled'; - var SOL_CACHE_FILE = null; - - var editor = ace.edit("input"); - var sessions = {}; - - var Range = ace.acequire('ace/range').Range; - var errMarkerId = null; - - var untitledCount = ''; - if (!getFiles().length || window.localStorage['sol-cache']) { - if(loadingFromGist) return; - // Backwards-compatibility - while (window.localStorage[SOL_CACHE_UNTITLED + untitledCount]) - untitledCount = (untitledCount - 0) + 1; - SOL_CACHE_FILE = SOL_CACHE_UNTITLED + untitledCount; - window.localStorage[SOL_CACHE_FILE] = window.localStorage['sol-cache'] || BALLOT_EXAMPLE; - window.localStorage.removeItem('sol-cache'); - } + var loadingFromGist = gistHandler.handleLoad(function(gistId) { + $.ajax({ + url: 'https://api.github.com/gists/'+gistId, + jsonp: 'callback', + dataType: 'jsonp', + success: function(response) { + if (response.data) { + if (!response.data.files) { + alert( "Gist load error: " + response.data.message ); + return; + } + loadFiles(response.data.files); + } + } + }); + }); - SOL_CACHE_FILE = getFiles()[0]; + // ----------------- storage -------------------- - var files = getFiles(); - for (var x in files) { - sessions[files[x]] = newEditorSession(files[x]); - } + var storageHandler = new StorageHandler(updateFiles); + window.syncStorage = storageHandler.sync; + storageHandler.sync(); - editor.setSession( sessions[SOL_CACHE_FILE] ); - editor.resize(true); - function newEditorSession(filekey) { - var s = new ace.EditSession(window.localStorage[filekey], "ace/mode/javascript"); - s.setUndoManager(new ace.UndoManager()); - s.setTabSize(4); - s.setUseSoftTabs(true); - sessions[filekey] = s; - return s; - } + // ----------------- editor ---------------------- + var editor = new Editor(loadingFromGist); // ----------------- tabbed menu ------------------- @@ -228,64 +104,14 @@ var run = function() { } }); - // ----------------- execution context ------------- - - var $vmToggle = $('#vm'); - var $web3Toggle = $('#web3'); - var $web3endpoint = $('#web3Endpoint'); - - if (web3.providers && web3.currentProvider instanceof web3.providers.IpcProvider) - $web3endpoint.val('ipc'); - - var executionContext = 'vm'; - $vmToggle.get(0).checked = true; - - $vmToggle.on('change', executionContextChange ); - $web3Toggle.on('change', executionContextChange ); - $web3endpoint.on('change', function() { - setProviderFromEndpoint(); - if (executionContext == 'web3') compile(); - }); - - function executionContextChange (ev) { - if (ev.target.value == 'web3' && !confirm("Are you sure you want to connect to a local ethereum node?") ) { - $vmToggle.get(0).checked = true; - executionContext = 'vm'; - } else { - executionContext = ev.target.value; - setProviderFromEndpoint(); - } - compile(); - } - - function setProviderFromEndpoint() { - var endpoint = $web3endpoint.val(); - if (endpoint == 'ipc') - web3.setProvider(new web3.providers.IpcProvider()); - else - web3.setProvider(new web3.providers.HttpProvider(endpoint)); - } - // ------------------ gist publish -------------- - var packageFiles = function() { - var files = {}; - var filesArr = getFiles(); - - for (var f in filesArr) { - files[fileNameFromKey(filesArr[f])] = { - content: localStorage[filesArr[f]] - }; - } - return files; - }; - $('#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 = packageFiles(); - var description = "Created using browser-solidity: Realtime Ethereum Contract Compiler and Runtime. \n Load this file by pasting this gists URL or ID at https://ethereum.github.io/browser-solidity/#version=" + getQueryParams().version + "&optimize="+ getQueryParams().optimize +"&gist="; + var files = editor.packageFiles(); + var description = "Created using browser-solidity: Realtime Ethereum Contract Compiler and Runtime. \n Load this file by pasting this gists URL or ID at https://ethereum.github.io/browser-solidity/#version=" + queryParams.get().version + "&optimize="+ queryParams.get().optimize +"&gist="; $.ajax({ url: 'https://api.github.com/gists', @@ -310,7 +136,7 @@ var run = function() { ); if (target === null) return; - var files = packageFiles(); + var files = editor.packageFiles(); var iframe = $('